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