Swift - JSQMessagesViewController Swift

Swift - JSQMessagesViewController with Swift

我正在开发一个聊天应用程序,我在向 JSQMessagesViewController

显示头像时遇到问题
override func collectionView(collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource! {

    var avatar = UIImage()

    let people = FIRDatabase.database().reference().child("people").child(senderId)
    people.observeEventType(.Value, withBlock: {
        snapshot -> Void in
        let dict = snapshot.value as! Dictionary<String, AnyObject>
        let imageUrl = dict["profileImage"] as! String
        if imageUrl.hasPrefix("gs://") {
            FIRStorage.storage().referenceForURL(imageUrl).dataWithMaxSize(INT64_MAX, completion: { (data, error) in
                if let error = error {
                    print("Error downloading: \(error)")
                    return
                }
                avatar = UIImage.init(data: data!)!

            })
        }
    })

    let AvatarJobs = JSQMessagesAvatarImageFactory.avatarImageWithPlaceholder(avatar, diameter: UInt(kJSQMessagesCollectionViewAvatarSizeDefault))

    return AvatarJobs
}

这里的问题是,当我试图从 firebase 中提取发件人的图像时,我得到的是一张空白图像,但是当我尝试使用这个 let AvatarJobs = JSQMessagesAvatarImageFactory.avatarImageWithPlaceholder(UIImage(named: "icon.png"), diameter: UInt(kJSQMessagesCollectionViewAvatarSizeDefault)) 它工作正常,什么你认为问题出在这里吗?谢谢!

我可以推荐一个替代方案吗?为什么你没有字典:

var avatars = [String: JSQMessagesAvatarImage]()

let storage = FIRStorage.storage()

并使用以下函数:

override func collectionView(collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource!
{
    let message = messages[indexPath.row]
    return avatars[message.senderId]
}

并在 viewDidLoad 中(或任何地方)创建头像

createAvatar(senderId, senderDisplayName: senderDisplayName, user: currentUser,  color: UIColor.lightGrayColor())

有函数

func createAvatar(senderId: String, senderDisplayName: String,  user: FBUser, color: UIColor)
{
    if self.avatars[senderId] == nil
    {
        //as you can see, I use cache
        let img = MyImageCache.sharedCache.objectForKey(senderId) as? UIImage

        if img != nil
        {
            self.avatars[senderId] = JSQMessagesAvatarImageFactory.avatarImageWithImage(img, diameter: 30)

            // print("from cache")
        }
        else if let photoUrl = user.pictureURL where user.pictureURL != ""
        {
       // the images are very small, so the following methods work just fine, no need for Alamofire here

            if photoUrl.containsString("https://firebasestorage.googleapis.com")
            {
                self.storage.referenceForURL(photoUrl).dataWithMaxSize(1 * 1024 * 1024) { (data, error) -> Void in
                    if (error != nil)
                    {
                        //deal with error
                    }
                    else
                    {
                        let newImage = UIImage(data: data!)

                        self.avatars[senderId] = JSQMessagesAvatarImageFactory.avatarImageWithImage(newImage, diameter: 30)

                        MyImageCache.sharedCache.setObject(newImage!, forKey: senderId, cost: data!.length)
                    }
                }
            }
            else if let data = NSData(contentsOfURL: NSURL(string:photoUrl)!)
            {
                let newImage = UIImage(data: data)!

                self.avatars[senderId] = JSQMessagesAvatarImageFactory.avatarImageWithImage(newImage, diameter: 30)

                MyImageCache.sharedCache.setObject(newImage, forKey: senderId, cost: data.length)
            }
            else
            {
                //etc. blank image or image with initials
            }
        }
    }
    else
    {
        //etc. blank image or image with initials
    }
}

对于缓存我有一个自定义 class

import Foundation

class MyImageCache
{
    static let sharedCache: NSCache =
    {
        let cache = NSCache()
        cache.name = "MyImageCache"
        cache.countLimit = 200 // Max 200 images in memory.
        cache.totalCostLimit = 20*1024*1024 // Max 20MB used.
        return cache
    }()
}

如果有帮助请告诉我

我建议尝试隔离您的问题。我不知道问题是否出在 JSQMessagesAvatarImageFactory 我认为问题可能是您在需要显示单元格时没有下载图像。在您尝试将它设置为您的头像之前,我会确保您从 fireBase 得到一些东西。闭包通常是我这样做的方式

func getImageForUser(id: String, completiion() -> Void) {

//Add your logic for retrieving from firebase

  let imageFromFirebase = firebaserReference.chiledWithID(id)
  completion(image)
}

然后在你的

override func collectionView(collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource! {
   var avatarImage = JSQAavatarImage()
   getImageForUser {
       self.avatarImage = JSQMessagesAvatarImageFactory.avatarImageWithPlaceholder(imageFromFirebase, diameter: UInt(kJSQMessagesCollectionViewAvatarSizeDefault))
       self.collectionView.reloadItemAtIndexPath(indexPath)
   }

这样它会等到响应返回,然后在响应返回时重新加载单元格。

如果您有任何其他问题,请告诉我。