首页 > 解决方案 > Downloading image from Firebase and adding it to an Array

问题描述

Basically what I got so far is an Array which includes every data that is necessary for my prototyp cell. I retrieve that data (image, name and brand) from Firebase. Now, I created a loop to retrieve everything from the Database, but my problem now, is that I cant add the "image" to my "tempShopCells.append()" method, because it is inside that loop and not reachable. The code:

func createArray(completion: @escaping ([ShopCell]) -> () ) {
    var tempShopCells: [ShopCell] = []
    let rootRef = Database.database().reference()
    let query = rootRef.child("tobacco").queryOrdered(byChild: "name")
    query.observeSingleEvent(of: .value) { (snapshot) in
        for child in snapshot.children.allObjects as! [DataSnapshot] {
            let value = child.value as? [String: Any];
            let name = value?["name"] as? String ?? "";
            let brand = value?["brand"] as? String ?? "";
            let iD = value?["iD"] as? String ?? "";
            let imageReference = Storage.storage().reference().child("tobaccoPictures").child("\(iD).jpg")
            imageReference.getData(maxSize: (1 * 1024 * 1024)) { (data, error) in
                if let _error = error{
                    print(_error)
                } else {
                    if let _data  = data {
                        let image: UIImage! = UIImage(data: _data)
                    }
                }
            }
            tempShopCells.append(ShopCell(productName: name, brandName: brand, productImage: image))
        }
        completion(tempShopCells)
    }

标签: iosswiftfirebase

解决方案


在初始化图像后立即移动将新元素附加到数组的行_data

if let _data = data {
     let image: UIImage! = UIImage(data: _data)
     tempShopCells.append(ShopCell(productName: name, brandName: brand, productImage: image))
}

另请注意,检索图像的数据是异步任务,因此完成的数据将是空数组。

所以我建议你使用DispatchGroup.

首先创建新的DispatchGroup. 然后在您要求图像数据之前,输入dispatchGroup您收到数据之后离开 dispatchGroup。当接收到每个图像的数据时,调用completion关闭dispatchGroup.notify(queue:)

let dispatchGroup = DispatchGroup()

for child in snapshot.children.allObjects as! [DataSnapshot] {
    ...
    dispatchGroup.enter()
    imageReference.getData(maxSize: (1 * 1024 * 1024)) { (data, error) in
        ... // error, appending to array, etc.
        dispatchGroup.leave()
    }    
}
dispatchGroup.notify(queue: .main) {
    completion(tempShopCells)
}

推荐阅读