1

JSQMessageView を使用すると、最初の読み込み時にすべてのアバターの画像 URL がないため、URL を取得して取得する非同期呼び出しがあり、次にアバターの画像が取得されます。

非同期プロセスからアバターを取得したら、プレースホルダーのアバター画像を更新するにはどうすればよいですか?

JSQMessageAvatarImageDataSource に関するいくつかのメモを見ましたが、ドキュメントには、キーやインデックスなどのパラメーターを持たない単一の画像のみを返すプロトコル メソッドが示されているため、このプロトコルを実装する方法がわかりません。

このユースケースを実装する方法の例はありますか?

これまでの私の実装

  override func collectionView(collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource! {

        let message = messages[indexPath.item]
        let diameter = UInt(collectionView.collectionViewLayout.incomingAvatarViewSize.width)


        if let avatar = avatars[message.senderDisplayName] {
            return avatar
        } else {

            // how do I update the avatars when i come back form the async call here

//            APIClient.instance.getUserThumbnail(Int(message.senderId)!, completion: { (url, error) -> () in
//                self.setupAvatarImage(message.senderDisplayName, imageUrl: url, diameter: 30)
//            })
            //default placeholder while the async call is happening
            return setupAvatarColor(message.senderDisplayName, diameter: diameter)


        }
    }
4

2 に答える 2

0

AlamofireImage キャッシュを使用して、アバターの読み込みと保存を行いました。これでセットアップが完了し、チャット コントローラーのすべてが次のようになりChatVC: JSQMessagesViewControllerます。

import Alamofire
import AlamofireImage

let imageCache = AutoPurgingImageCache(
    memoryCapacity: 60 * 1024 * 1024,
    preferredMemoryUsageAfterPurge: 20 * 1024 * 1024
)

var images = [UIImage]()
var ImageCache = [String:UIImage]()
var imagesURL = [String]()

override func collectionView(_ collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAt indexPath: IndexPath!) -> JSQMessageAvatarImageDataSource! {
    let placeHolderImage = UIImage(named: "nouser")
    var avatarImage = JSQMessagesAvatarImageFactory.avatarImage(with: placeHolderImage, diameter: UInt(kJSQMessagesCollectionViewAvatarSizeDefault))
    let profileImageURL = messages[indexPath.row].avatarImage

    if let avatar = ImageCache[profileImageURL] {
        avatarImage = JSQMessagesAvatarImageFactory.avatarImage(with: avatar, diameter: UInt(kJSQMessagesCollectionViewAvatarSizeDefault))
    } else {
        Alamofire.request(profileImageURL)
            .responseImage { response in
                debugPrint(response.result)

                if let image = response.result.value {
                    print("image downloaded: \(image)")

                    self.ImageCache[profileImageURL] = image

                    avatarImage = JSQMessagesAvatarImageFactory.avatarImage(with: image, diameter: UInt(kJSQMessagesCollectionViewAvatarSizeDefault))
                    self.finishReceivingMessage()
                } else {
                    print("error getting image at cell")
                }
        }
    }

    return avatarImage
}
于 2017-10-23T06:48:30.747 に答える
-1

これが私の方法です。画像が来ることがわかっているアバターのイニシャルを入れていないことに注意してください。画像がないものは既に特定しており、別の場所で avatarImageWithUserInitials: を使用しました。

基本的に、avatarImage が既に存在する限り、新しいイメージを非同期的に渡すことができ、アバターは準備が整うとプレースホルダーを自動的に更新します。

UIImage *placeHolderImage = [UIImage imageNamed:@"Default User"];
JSQMessagesAvatarImage *avatarImage = [[JSQMessagesAvatarImage alloc] initWithAvatarImage:nil highlightedImage:nil placeholderImage:placeHolderImage];

[self.avatarCache setObject:avatarImage forKey:message.user.userID.stringValue];

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{

    NSData *data = [NSData dataWithContentsOfURL:imageURL];

    UIImage *imageFromData = [UIImage imageWithData:data];
    UIImage *circularImage = [JSQMessagesAvatarImageFactory circularAvatarHighlightedImage:imageFromData withDiameter:kJSQMessagesCollectionViewAvatarSizeDefault];

    dispatch_async(dispatch_get_main_queue(), ^{

        avatarImage.avatarImage = circularImage;
        avatarImage.avatarHighlightedImage = circularImage;
    });
});
于 2015-12-23T20:58:23.557 に答える