1

我开发一个聊天应用,我在显示头像问题我JSQMessagesViewController斯威夫特 - 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))它工作正常,你认为这里的问题是什么?谢谢!

回答

3

如果我可能会建议一个替代方案?你为什么不有一本字典:

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 
    } 
} 

缓存我有一个自定义类

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 
    }() 
} 

让我知道这是否有助于

+0

这是一个很好的解决方案,只需要在应用程序中触发一次即可为您提供化身。因此,优化您的应用程序以加快载入速度,因为您不必为每个单元格获取图像,从而创建单元格。 –

+0

嗨!这是什么类型的MyImageCache?这是AnyObject吗?同样在这一行'func createAvatar(senderId:String,senderDisplayName:String,user:FIRUser,color:UIColor)''我将'FBUser'替换为'FIRUser',并且在这行中出现这个错误'else if let photoUrl = user.pictureURL其中user.pictureURL!=“”'这里似乎是什么问题?谢谢! –

+0

用我用于缓存的自定义类更新了我的答案。我还将用户类中的用户数据(user.pictureUR)保存到数据库中,您将不得不自定义数据,而只需传递url。 –

2

我建议试图找出你的问题。我不知道这个问题是否与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) 
    } 

这样,它等待,直到反应回来,然后重新装入电池,一旦它的存在。

让我知道如果您有任何其他问题。

+0

嘿丹尼尔,我遵循你的意见,这似乎是相当不错的。只有一件事不适合我。也许你可以看看这里:https://stackoverflow.com/questions/46228051/jsqavatarimage-doesnt-show-anything-although-uiimage-is-loaded – AlexVilla147