从 JSQMessagesController 中的 URL 字符串分配头像

Assigning avatars from URL string in JSQMessagesController

我在文档中找不到太多用处,Swift 中的示例项目只有硬编码的头像,所以也没什么用。我也看到了 this question 但那个例子也不适用我的情况。

我让我的用户使用 Facebook 登录,图形请求获取他们的个人资料图片,然后将其作为字符串存储在 Firebase 和用户对象中(我指的是图像的 URL 路径)。

这是我的cellForItem函数

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = super.collectionView(collectionView, cellForItemAt: indexPath) as! JSQMessagesCollectionViewCell
    let message = messages[indexPath.item]

    if message.senderId == senderId {
        cell.textView?.textColor = UIColor.white
    } else {
        cell.textView?.textColor = UIColor.black
    }
    return cell
}

这是我应该设置头像的地方:

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

    let message = messages[indexPath.item]

    if let messageID = message.senderId {
        let users = [User]()
        let userProfilePictures = users[indexPath.row].profilePicture
    }

    return ????
}

有人知道我怎样才能将个人资料图片设置为正确的头像吗?

编辑:这是我的图像缓存代码:

let imageCache = NSCache<NSString, UIImage>()

扩展 UIImageView {

func loadImageUsingCacheWithUrlString(_ urlString: String) {

    self.image = nil

    // Check cache for image first
    if let cachedImage = imageCache.object(forKey: urlString as NSString) {
        self.image = cachedImage
        return
    }

    // Otherwise fire off a new download
    Alamofire.request(urlString)
        .responseImage { response in

            if let downloadedImage = response.result.value {
                // image is here.
                imageCache.setObject(downloadedImage, forKey: urlString as NSString)
                self.image = downloadedImage
            }
        }
}

}

呀,你要找的是 'JSQMessagesAvatarImageFactory' Documentation Link

既然你有你的 userProfilePicture 那么你只需要获取那个 url 的图像数据。您可以通过多种方式执行此操作,我个人喜欢使用一个为您处理捕获的框架。 SDWebImage or AlamofireImage 或您想通过其他方式获取该数据。

我喜欢 AlimofireImage 所以这就是我将在这里展示的内容。为了做到这一点,我不必为每个单元格发出下载请求,我使用 senderID 作为键将它们保存在字典中。如果字典条目在那里,我不会提出请求。定义你的字典。

var avatarDictionary: [String:UIImage] = [:]

然后在检索到对话调用的所有消息后 getAllAvatars()

func getAllAvatars() {
    for message in messages {
        guard let key = message.senderID else { return }
        if avatarDictionary[key] == nil {
            try? _ = imageDownloader?.download(URLRequest(url: API.userPhoto(userID: key).asURL()), completion: { (response) in
                guard let image = response.result.value else { return }
                self.avatarDictionary[key] = image
                self.collectionView.reloadData()
            })
        }
    }
}

API.userPhoto(userID: key).asURL() 是您的图像数据源的 url,因此这就是您要为您拥有的 url 所做的更改。

您还可以研究一些其他方法。我制作了自己的功能,为没有图像的用户提供 defaultAvatar。看起来像这样

func blankAvatar(message: Message) -> JSQMessageAvatarImageDataSource {
    return JSQMessagesAvatarImageFactory.avatarImage(withUserInitials: initialsFrom(firstName: message.fistName, lastName: message.lastName), backgroundColor: UIColor.gray, textColor: UIColor.white, font: UIFont.systemFont(ofSize: 14), diameter: UInt(kJSQMessagesCollectionViewAvatarSizeDefault))
}

然后您可以 return 图像(如果存在)或空白头像(如果不是来自 avatarImageDataForItemAt 方法

return avatarDictionary[id] == nil ? blankAvatar(message: message) : JSQMessagesAvatarImageFactory.avatarImage(with: avatarDictionary[id], diameter: UInt(kJSQMessagesCollectionViewAvatarSizeDefault))

另外不要忘记为 collectionView 设置头像的大小

 collectionView?.collectionViewLayout.incomingAvatarViewSize = avatarSize
 collectionView?.collectionViewLayout.outgoingAvatarViewSize = avatarSize

否则他们根本不会出现。

如果您需要更多帮助,请告诉我。