返回值与完成处理程序

时间:2017-09-16 11:24:58

标签: ios firebase swift3 return completionhandler

我创建了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 ?? "")
            }
        })
    }
}

在viewDidLoad中调用SetAvatarImages。

要从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函数中下载图像时突然崩溃了。我在每次开始崩溃之前唯一改变的是我删除了控制台中的断点以查看其工作速度有多快...有没有人知道它为什么会崩溃。 是的,我知道为图像添加一些缓存会更好,但首先必须解决这个问题!

1 个答案:

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

下一步停止缓存!