2017-09-16 76 views
0

我創建了setAvatarImage函數來下載一個UIImage,然後它將在默認集合視圖函數中返回。我可以在控制檯看到UIImage正在下載,因此返回值應該是UIImage。但是,收集視圖中不顯示圖像。將返回值與完成處理程序結合使用

func setAvatarImages(_ senderUid: String!, completionhandler: @escaping (UIImage!) -> Void) { 

    let ref = DatabaseReference.users(uid: senderUid).reference() 
    ref.observe(.value, with: { (snapshot) in 
     let user = User(dictionary: snapshot.value as! [String : Any]) 
     user.downloadProfilePicture(completion: { (image, error) in 
      if image != nil { 
       let profileImage = image 
       print(profileImage!) 
       completionhandler(profileImage!) 
      } else if error != nil { 
       print(error?.localizedDescription ?? "") 
      } 
     }) 
    }) 
} 

override func collectionView(_ collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAt indexPath: IndexPath!) -> JSQMessageAvatarImageDataSource! { 

    let message = messages[indexPath.item] 
    var avatarImage: JSQMessagesAvatarImage! 
    setAvatarImages(message.senderUID) { (profileImage) in 
     avatarImage = JSQMessagesAvatarImageFactory.avatarImage(with: profileImage, diameter: UInt(kJSQMessagesCollectionViewAvatarSizeDefault)) 
     print(avatarImage) 
    } 
    return avatarImage 
} 

我覺得異步返回函數有問題。但我認爲,給setAvatarImage函數一個完成處理程序應該可以解決這個問題。 任何人都可以給我一些建議,讓下載的圖像返回!

編輯!

考慮到Alex的建議我改變了setAvatarImage函數。 首先我創建了一個詞典:

var profileImages = [String : UIImage]() 

其目的是讓所有的圖像轉換成profileImages與user.uid作爲viewDidLoad中中的關鍵。

func setAvatarImages() { 

    for user in chat.users { 
     print(user.fullName) 
     user.downloadProfilePicture(completion: { (image, error) in 
      print(image!) 
      if let profileImage = image { 
       self.profileImages[user.uid] = profileImage 
      } else if error != nil { 
       print(error?.localizedDescription ?? "") 
      } 
     }) 
    } 
} 

SetAvatarImages在viewDidLoad中被調用。

爲了從JSQMessagesViewController我這樣做,默認功能返回AvatarImage:

override func collectionView(_ collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAt indexPath: IndexPath!) -> JSQMessageAvatarImageDataSource! { 

    let message = messages[indexPath.item] 
    let avatarImage = JSQMessagesAvatarImageFactory.avatarImage(with: profileImages[message.senderUID], diameter: UInt(kJSQMessagesCollectionViewAvatarSizeDefault)) 
    return avatarImage 
} 

很酷的事情是,它的工作,對於一些嘗試。但是,在user.downloadProfileImage函數中下載圖像時突然崩潰。我在每次開始崩潰之前改變的唯一一件事是,我刪除了控制檯中的突破點以查看它的工作速度。有沒有人知道它爲什麼現在崩潰了。 是的,我知道最好爲圖像添加一些緩存,但首先這個問題必須解決!

+0

我不親自使用JSQMessages,但是當你看着他們在Github上的項目時,它的語法看起來不同,所以你可能想看看那裏:)。同樣對於你的圖像變量,我建議你不要大寫它,因爲大寫的名字通常是類和結構名稱,當有人讀你的代碼時它可能會令人困惑 – Alex

+0

是的,我看了一下,但邏輯上我看不出在我使用的方法與他們的代碼相比。 downloadProfilePicture函數適用於其他應用程序快速下載圖片火箭。但感謝您的回覆,我會再次看看示例項目 – AlexVilla147

+0

嗯,我剛剛注意到,您是否嘗試將返回avatarImage放入setAvatarImages完成塊中?因爲你的完成塊是異步調用的,所以在你完成塊被調用之前,調用「return avatarImage」這一行就會被調用。這可能是問題 – Alex

回答

0

終於明白了!

我只需要添加一個完成處理程序到setAvatarImages函數!

func setAvatarImages(completion: @escaping ([String : UIImage]) -> Void) { 

    for user in chat.users { 
     print(user.fullName) 
     user.downloadProfilePicture(completion: { (image, error) in 
      print(image!) 
      if let profileImage = image { 
       self.profileImages[user.uid] = profileImage 
       completion(self.profileImages) 
      } else if error != nil { 
       print(error?.localizedDescription ?? "") 
      } 
     }) 
    } 
} 

,然後在viewDidLoad中

setAvatarImages(completion: { (profileUserImages) in 
     print(profileUserImages) 
    }) 

下一站緩存!