Firebase iOS:下载TableView图像 - 最佳实践

时间:2017-04-05 10:45:00

标签: ios firebase-storage

我按照Ray Wenderlich(Link)的Firebase教程,采用他的方式初始化对象(在我的情况下为#34;位置")和来自observe-method的快照:

课程地点:

init(snapshot: FIRDataSnapshot) {
    identifier = snapshot.key
    let snapshotValue = snapshot.value as! [String : AnyObject]
    type = snapshotValue["type"] as! String
    name = snapshotValue["name"] as! String
    address = snapshotValue["address"] as! String
    latitude = Double(snapshotValue["latitude"] as! String)!
    longitude = Double(snapshotValue["longitude"] as! String)!
    avatarPath = snapshotValue["avatarPath"] as! String

    ref = snapshot.ref
}

LocationsViewController:

databaseHandle = locationsRef?.queryOrdered(byChild: "name").observe(.value, with: { (snapshot) in

        var newLocations:[Location] = []

        for loc in snapshot.children {
            let location = Location(snapshot: loc as! FIRDataSnapshot)

            newLocations.append(location)
        }

        self.locations = newLocations
        self.tableView.reloadData()
})

这真的很像魅力,但现在我试图加载存储参考" avatarPath"下存储的图像。 我的尝试有效但图像需要花费时间来加载。是否有更好的方式/地方加载这些图像?

我的尝试1:

databaseHandle = locationsRef?.queryOrdered(byChild: "name").observe(.value, with: { (snapshot) in

        var newLocations:[Location] = []

        for loc in snapshot.children {
            let location = Location(snapshot: loc as! FIRDataSnapshot)

            newLocations.append(location)
        }

        self.locations = newLocations
        self.tableView.reloadData()

        //Load images       
        for loc in self.locations {
            let imagesStorageRef = FIRStorage.storage().reference().child(loc.avatarPath)
            imagesStorageRef.data(withMaxSize: 1*1024*1024, completion: { (data, error) in
                if let error = error {
                    print(error.localizedDescription)
                } else {
                    loc.avatarImage = UIImage(data: data!)!
                    self.tableView.reloadData()
                }
            })
        }
})

我的第二次尝试(位置类内):

init(snapshot: FIRDataSnapshot) {
    identifier = snapshot.key
    let snapshotValue = snapshot.value as! [String : AnyObject]
    type = snapshotValue["type"] as! String
    name = snapshotValue["name"] as! String
    address = snapshotValue["address"] as! String
    latitude = Double(snapshotValue["latitude"] as! String)!
    longitude = Double(snapshotValue["longitude"] as! String)!
    avatarPath = snapshotValue["avatarPath"] as! String

    ref = snapshot.ref

    super.init()
    downloadImage()
}

func downloadImage() {
    let imagesStorageRef = FIRStorage.storage().reference().child(self.avatarPath)
    imagesStorageRef.data(withMaxSize: 1*1024*1024, completion: { (data, error) in
        if let error = error {
            print(error.localizedDescription)
        } else {
            self.avatarImage = UIImage(data: data!)!
        }
    })
}

提前谢谢!

尼科

2 个答案:

答案 0 :(得分:1)

首次尝试将代码更改为:

DispatchQueue.main.async {
       for loc in self.locations {
            let imagesStorageRef = FIRStorage.storage().reference().child(loc.avatarPath)
            imagesStorageRef.data(withMaxSize: 1*1024*1024, completion: { (data, error) in
                if let error = error {
                    print(error.localizedDescription)
                } else {
                    loc.avatarImage = UIImage(data: data!)!
                    self.tableView.reloadData()
                }
            })
        }
}

答案 1 :(得分:1)

您可以实现的最佳方法是在加载单元格函数时加载异步。我的意思是:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
DispatchQueue.main.async {
   let imagesStorageRef = FIRStorage.storage().reference().child(self.locations[indexPath.row].avatarPath)
        imagesStorageRef.data(withMaxSize: 1*1024*1024, completion: { (data, error) in
            if let error = error {
                print(error.localizedDescription)
            } else {
                locations[indexPath.row].avatarImage = UIImage(data: data!)!
tableView.reloadRows(at indexPaths: [indexPath], with animation: .none)
            }
        })
    }

}