斯威夫特 - JSQMessagesViewController与斯威夫特
我开发一个聊天应用,我在显示头像问题我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))
它工作正常,你认为这里的问题是什么?谢谢!
如果我可能会建议一个替代方案?你为什么不有一本字典:
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
}()
}
让我知道这是否有助于
我建议试图找出你的问题。我不知道这个问题是否与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)
}
这样,它等待,直到反应回来,然后重新装入电池,一旦它的存在。
让我知道如果您有任何其他问题。
嘿丹尼尔,我遵循你的意见,这似乎是相当不错的。只有一件事不适合我。也许你可以看看这里:https://stackoverflow.com/questions/46228051/jsqavatarimage-doesnt-show-anything-although-uiimage-is-loaded – AlexVilla147
这是一个很好的解决方案,只需要在应用程序中触发一次即可为您提供化身。因此,优化您的应用程序以加快载入速度,因为您不必为每个单元格获取图像,从而创建单元格。 –
嗨!这是什么类型的MyImageCache?这是AnyObject吗?同样在这一行'func createAvatar(senderId:String,senderDisplayName:String,user:FIRUser,color:UIColor)''我将'FBUser'替换为'FIRUser',并且在这行中出现这个错误'else if let photoUrl = user.pictureURL其中user.pictureURL!=“”'这里似乎是什么问题?谢谢! –
用我用于缓存的自定义类更新了我的答案。我还将用户类中的用户数据(user.pictureUR)保存到数据库中,您将不得不自定义数据,而只需传递url。 –