如何使用JSQMessageAvatarImageDataSource加载头像图像异步

时间:2015-09-18 20:34:48

标签: jsqmessagesviewcontroller

使用JSQMessageView我没有在初始加载时为所有我的头像设置图像网址,所以我有一个异步调用,然后获取网址 - 然后是头像的图像。

如果我拥有异步流程中的头像,如何更新占位符头像?

我看到了一些关于JSQMessageAvatarImageDataSource的注释,但是文档显示的协议方法只返回单个图像,没有参数,如key或index - 所以不确定如何实现这个协议。

如何实现此用例的任何示例?

到目前为止我的实施

  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)


        }
    }

2 个答案:

答案 0 :(得分: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
}

答案 1 :(得分:-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;
    });
});