从firebase存储中检索图像以在tableView(Swift)上显示

时间:2016-06-20 02:28:50

标签: arrays swift asynchronous firebase firebase-storage

来自的扩展问题 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)
希望能得到一些建议!

3 个答案:

答案 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()
            }
     })