"For Loop"内的 Swift 4 Firebase 存储图像下载

标签 swift firebase for-loop firebase-realtime-database firebase-storage

我有一个包含多个返回节点的 firebase 快照:

Screenshot of the database

并尝试使用“for 循环”来遍历它。在每个循环中,我想从 Firebase 存储下载一个图像文件:

let projectReviews = projectDB.queryOrdered(byChild: "contractorID").queryEqual(toValue: contractorID)

    projectReviews.observeSingleEvent(of: .value, with: { snapshot in

        for child in snapshot.children.allObjects as! [DataSnapshot] {
            guard let value = child.value as? [String: AnyObject] else { continue }
                if value["projectStatus"] as? String ?? "" == "Completed" && value["recommend"] != nil {

                counter += 1
                    print("this is how many times this for loop has go through \(counter) at \(child.key)")

                    //Fetch and display the data.

                    var downloadURL :String
                    downloadURL = "Projects/" + "\(child.key)" + "--00"
                    print("---" + downloadURL)
                    print("downloadURL before download---" + downloadURL )
                    var imgURL = self.storageRef.child("")
                    imgURL = self.storageRef.child(downloadURL)
                    print("downloadURL after assign download URL ---" + downloadURL )
                    imgURL.getData(maxSize: Int64(1 * 1024 * 2000), completion: { (data, error) in
                        if let error = error {
                            print(error)
                            print("===This is image Download error on=== \n")
                            print(counter)
                            print("\(downloadURL)")
                            return
                        } else {
                        //Do something

                        }
                    })

}

正如您在这里看到的,我已经放置了一些打印命令来告诉我 downloadURL 变量发生了什么。

问题:

在第二个循环中,downloadURL 变量,当实际尝试下载文件时,仍然使用前一个循环的值,即使在“getData”之前的值是正确的:

this is how many times this for loop has go through 1 at vzzzzzzzzzzzzzz----0001
---Projects/vzzzzzzzzzzzzzz----0001--00
downloadURL before download---Projects/vzzzzzzzzzzzzzz----0001--00
downloadURL after assign download URL ---Projects/vzzzzzzzzzzzzzz----0001--00
this is how many times this for loop has go through 2 at vzzzzzzzzzzzzzz----0002
---Projects/vzzzzzzzzzzzzzz----0002--00
downloadURL before download---Projects/vzzzzzzzzzzzzzz----0002--00
downloadURL after assign download URL ---Projects/vzzzzzzzzzzzzzz----0002--00
Error Domain=FIRStorageErrorDomain Code=-13010 "Object Projects/vzzzzzzzzzzzzzz----0001--00 does not exist."     UserInfo={object=Projects/vzzzzzzzzzzzzzz----0001--00, bucket=bafo-1c3c8.appspot.com, ResponseBody=<?xml version='1.0' encoding='UTF-8'?><Error><Code>NoSuchKey</Code><Message>The specified key does not exist.</Message><Details>No such object: bafo-1c3c8.appspot.com/Projects/vzzzzzzzzzzzzzz----0001--00</Details></Error>, data=<3c3f786d 6c207665 7273696f 6e3d2731 2e302720 656e636f 64696e67 3d275554 462d3827 3f3e3c45 72726f72 3e3c436f 64653e4e 6f537563 684b6579 3c2f436f 64653e3c 4d657373 6167653e 54686520 73706563 69666965 64206b65 7920646f 6573206e 6f742065 78697374 2e3c2f4d 65737361 67653e3c 44657461 696c733e 4e6f2073 75636820 6f626a65 63743a20 6261666f 2d316333 63382e61 70707370 6f742e63 6f6d2f50 726f6a65 6374732f 76353756 5467595a 4c685170 7a57486a 4c306131 6b733150 494a6d31 52695339 61574631 4f6a5854 63635963 524b6453 67525a6f 54473832 2d2d2d2d 30303031 2d2d3030 3c2f4465 7461696c 733e3c2f 4572726f 723e>, NSLocalizedDescription=Object Projects/vzzzzzzzzzzzzzz----0001--00 does not exist., ResponseErrorDomain=com.google.HTTPStatus, ResponseErrorCode=404}
Projects/vzzzzzzzzzzzzzz----0001--00

正如您从日志中看到的,如果我在 getData 闭包中打印 downloadURL 变量,它包含之前的值“vzzzzzzzzzzzzzz----0001”

我的做法是否受支持?如果不是,我该如何解决它,以便图像可以在同一个循环中显示?

最佳答案

找到解决方案。这应该能够适用于使用 Firebase 数据库进行异步调用的所有情况。

这是一个由两部分组成的解决方案。

首先,定义一个回调函数来查询和存储数据,作为一个类,在一个数组中:

  func getList(callback: @escaping ((_ data:[reviewContent]) -> Void)) {
    var contentArray :[content] = [content]()
    let someDB = dbRef!.child("someDB")

    let returns = someDB.queryOrdered(byChild: "contractorID").queryEqual(toValue: someValue)

    returns.observe(.value, with: {(snapshot) in
        print(snapshot.childrenCount)

        for child in snapshot.children.allObjects as! [DataSnapshot] {
            guard let value = child.value as? [String: AnyObject] else { continue }

            let contentEntry = content()
            contentEntry.ID = child.key
            //store any additional values where defined in the class

            contentArray.append(contentEntry)

        }

        print("Array now has \(contentArray.count)")
        callback(contentArray)

    }) {(error) in print(error.localizedDescription)}
}

第二,在 viewDidLoad() 中运行这个 func,并使用回调来使用带有 for 循环的数组条目:

    getList { (data:[content]) in
        print("this is data from call back" )
        print(data)


        for contentEntry in data {
            print(contentEntry.ID)


                                    imgURL = self.storageRef!.child(contentEntry.ID)

                                    imgURL.getData(maxSize: Int64(1 * 1024 * 2000), completion: { (imageData, error) in
                                        if let error = error {
                                            print(error)
                                            print("===This is image Download error on=== \n")
                                            print("\(contentEntry.ID)")
                                            return
                                        } else {
                                            print("===This is image Download URL was used=== \n")
                                            print("\(contentEntry.ID)")
                                            print(imageData)
                                        }
                                    })
        }
    }

希望这对您有所帮助。

注意,part 1中数组中要存储的数据最好定义一个类。它还使第二部分的回调变得更加容易。

关于 "For Loop"内的 Swift 4 Firebase 存储图像下载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50455975/

相关文章:

iOS 已弃用的 dataWithContentsOfMappedFile 替换

ios - 解析查询,图像数组返回空

iOS:何时选择 Cocoa Touch 静态库或框架?

ios - 在 swift 中获取值(value)的首选方式是什么,var 还是 func?

angularjs - 属性 'filter' 在类型 'FirebaseListObservable' 上不存在

swift - 如何在 Swift 中从 Firebase 存储和检索数据

android - 发布版本中的写入数据缺少 Firebase 时间戳

java - 不好的做法?省略循环条件

c++ - 这是 C++11 for 循环的已知缺陷吗?

r - 如何将 for 循环与特殊 seq 一起使用