来自的扩展问题 New Firebase retrieve data and put on the tableView (Swift)
通过将Firebase代码移动到viewDidLoad,Post的所有文本部分都可以显示。但是我仍然无法将图像放到tableView中。我检查了图像检索并且它成功了,我想我从Firebase检索的图像是在post数组中。
这是我的修正码:
struct Post {
var username: String?
var postText: String?
var time: String?
var userPhoto: UIImage?
var postPhoto: UIImage?
var url: String?
var userPhotoUrl:String?
init(data: NSDictionary) {
username = data["username"] as? String
postText = data["postText"] as? String
time = data["time"]as? String
userPhoto = data["userPhoto"] as? UIImage
postPhoto = data["postPhoto"] as? UIImage
url = data["postPhoto"] as? String
userPhotoUrl = data["userPhoto"] as? String
}
}
我的Post结构希望它可能有所帮助!
numpy.nan_to_num(x)
希望能得到一些建议!
答案 0 :(得分:6)
只需更改以下方法
即可func downloadPost(){
let userPostRef = self.databaseRef.child("posts")
userPostRef.queryOrderedByChild("time").observeEventType(.ChildAdded, withBlock: {(snapshot) in
if let postAdd = snapshot.value as? NSDictionary {
print("\(snapshot.value)")
let url = snapshot.value?["postPhoto"] as! String
let userPhotoUrl = snapshot.value?["userPhoto"] as! String
var myPost = Post(data: postAdd) //variable change to "var" because going to modify
let url2 = NSURL(string: url) //postPhoto URL
let data = NSData(contentsOfURL: url2!) // this URL convert into Data
if data != nil { //Some time Data value will be nil so we need to validate such things
myPost.postPhoto = UIImage(data: data!)
}
let url3 = NSURL(string: userPhotoUrl) //userPhoto URL
let data2 = NSData(contentsOfURL: url3!) //Convert into data
if data2 != nil { //check the data
myPost.userPhoto = UIImage(data: data2!) //store in image
}
self.posts.insert(myPost, atIndex: 0) // then add the "myPost" Variable
print(self.posts.count)
}
self.tableView.reloadData() // finally going to load the collection of data in tableview
})
}
它的加载时间很长。因为转换图像并将其存储在主队列中。
另一种方法是存储URL并访问tableview显示屏上的URL。可以在imageview中应用异步加载。
答案 1 :(得分:2)
看起来这里的问题是你的帖子永远不会获取照片信息,因为这些照片是异步下载的。
使用伪代码,您正在做的是:
Get information from database
Create post object
Begin downloading post photo
Populate post object with post photo
Begin downloading user photo
Populate post object with user photo
Return post object
发生的事情是在下载照片之前返回post对象(因为dataWithMaxSize:completion:
调用是异步的)。你最终需要做的事情看起来更像是:
Get information from database
Create post object
Begin downloading post photo, etc.
Begin downloading user photo, etc.
Return post object, now that it's fully populated
这是一种通常被称为"回调地狱"的范例,因为你非常深入地嵌入异步代码并且它更难以阅读和调试。 JavaScript发明了Promises来解决这个问题,但不幸的是,Swift并没有为这样的事情提供一流的支持(guard
在这方面是一个很好的举措)。像Bolts这样的库使用异步框架看起来更加同步,但同样,代码变得更加复杂。
你可以做些事情(在创建对象之前添加信号量/互斥量并等待下载完成),但这些是非常高级的概念,我在尝试之前掌握了同步/异步编程。
答案 2 :(得分:1)
删除这两行:
userPhoto = data["userPhoto"] as? UIImage
postPhoto = data["postPhoto"] as? UIImage
更新此代码:
FIRStorage.storage().referenceForURL(url).dataWithMaxSize(10 * 1024 * 1024, completion: { (data, error) in
dispatch_async(dispatch_get_main_queue()) {
myPost.postPhoto = UIImage(data: data!)
self.tableView.reloadData()
}
})
FIRStorage.storage().referenceForURL(userPhotoUrl).dataWithMaxSize(10 * 1024 * 1024, completion: { (data, error) in
dispatch_async(dispatch_get_main_queue()) {
myPost.userPhoto = UIImage(data: data!)
self.tableView.reloadData()
}
})