Swift 4:从Firebase存储中获取图像并将其显示在表格视图中

时间:2018-08-27 22:41:31

标签: ios firebase firebase-realtime-database swift4 firebase-storage

我还没有找到任何很好的示例/代码来从Firebase存储/数据库中获取图像并将其显示在基本表视图的单元格中。我看着here,但发现没有任何效果。有人可以举一个完整的例子吗?

下面是我试图使其工作的代码:

import UIKit
import FirebaseStorage
import FirebaseDatabase
import FirebaseAuth
import Firebase

class TableViewController: UITableViewController {

        //TableView datasource methods

        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

            let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
            self.downloadImages(cell: cell, folderPath: "\(Storage.storage().reference().child((Auth.auth().currentUser?.uid)!).child("post\(takePicViewController().finalPost + PhotoArray.sharedInstance.numberPost)").child(ImageUploadManager().imageName))", success: { (img) in
                print(img)
            }) { (error) in
                print(error)
            }

//            cell.imageView?.image = PhotoArray.sharedInstance.photosArray[indexPath.row] as? UIImage
            return cell
        }

        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            let numberOfRowsInSection = PhotoArray.sharedInstance.photosArray
            return numberOfRowsInSection.count 
        }

    func downloadImages(cell: UITableViewCell, folderPath:String,success:@escaping (_ image:UIImage)->(),failure:@escaping (_ error:Error)->()){
        for i in 0 ..< 194{
            // Create a reference with an initial file path and name
            let reference = Storage.storage().reference().child((Auth.auth().currentUser?.uid)!).child("post\(takePicViewController().finalPost + PhotoArray.sharedInstance.numberPost)").child(ImageUploadManager().imageName)
            reference.getData(maxSize: (1 * 1024 * 1024)) { (data, error) in
                if let _error = error{
                    print(_error)
                    failure(_error)
                } else {
                    if let _data  = data {
                        let myImage:UIImage! = UIImage(data: _data)
                        success(myImage)
                    }
                }
//                let cell = self.tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
                cell.imageView?.image = UIImage(data: data!)
            }

        }
    }

}

我也尝试过以下代码:

以VC开头,请执行以下操作:

    // Firebase services
var database: Database!
var storage: Storage!

// Initialize Database, Auth, Storage
override func viewDidLoad() {
    database = Database.database()
    storage = Storage.storage()
}

然后我在 tableView_cellforRowAt indexPath 函数内部调用该函数,如下所示。然后我返回细胞

       let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
       loadArrayOfImages(cell: cell)

       return cell

我调用的函数如下:

    func loadArrayOfImages(cell: UITableViewCell) {

    let dbRef = database.reference().child((Auth.auth().currentUser?.uid)!).child("post\(takePicViewController().finalPost + PhotoArray.sharedInstance.numberPost)").child(ImageUploadManager().imageName)
    dbRef.observe(.childAdded, with: { (snapshot) in
        // Get download URL from snapshot
        let downloadURL = snapshot.value as! String
        // Create a storage reference from the URL
        let storageRef = self.storage.reference(forURL: downloadURL)
        // Download the data, assuming a max size of 1MB (you can change this as necessary)
        storageRef.getData(maxSize: 10 * 1024 * 1024) { (data, error) -> Void in
            // Create a UIImage, add it to the array
            let pic = UIImage(data: data!)
            self.picArray.append(pic!)
            cell.imageView?.image = pic
        }
    })

   }
}

我似乎没有收到任何错误,并且该应用程序也没有崩溃,但是当我按下一个按钮将我带到电视上时,它只是空白。

1 个答案:

答案 0 :(得分:0)

可能就像重新加载tableView一样简单。请记住,您对Firebase服务器的数据请求不会立即返回,因为它是一个网络调用,因此,可能是您的表在数据返回之前就已经“设置”了自己。为了解决这个问题,您应该使用tableView.reloadData()。您可以将其放在loadArrayOfImages()函数的末尾,如下所示:

...
cell.imageView?.image = pic
tableView.reloadData()