无法在Firebase API回调块

时间:2017-03-14 06:12:43

标签: ios json swift firebase firebase-storage

我尝试在Xcode 8上使用Swift创建此功能。在我使用firebase功能获取网址后,我无法将url值分配给imageURL

我尝试了一种解决方法 - 将imageURL放在函数之外,并将url函数指定给self.imageURL,它完美无缺。但是,我试图将其设为静态函数,因此我无法使用该解决方法。有谁知道如何解决这个问题?

func createImageDownloadURL(path: String) -> URL? {
    // Create a reference to the file you want to download
    let storage = FIRStorage.storage()
    let storageRef = storage.reference()
    let imageRef = storageRef.child(path)
    var imageURL: URL?

    // Fetch the download URL

    imageRef.downloadURL { (url: URL?, error: Error?) in
        if error != nil {
            // Handle any errors
            print(error!)
        } else {
            // Get the download URL for image
            DispatchQueue.main.async {
                // Run UI Updates
                print(imageURL)  // output looks perfectly fine
                imageURL = URL(string: url!.absoluteString) // This is where the problem is
            }
        }
    }
    print(imageURL) // output is "nil"
    return imageURL
}

1 个答案:

答案 0 :(得分:2)

这就是你所需要的:)

func createImageDownloadURL(path: String,completionBlock : @escaping (URL?) -> ()) {
    // Create a reference to the file you want to download
    let storage = FIRStorage.storage()
    let storageRef = storage.reference()
    let imageRef = storageRef.child(path)
    var imageURL: URL?

    // Fetch the download URL

    imageRef.downloadURL { (url: URL?, error: Error?) in
        if error != nil {
            // Handle any errors
            print(error!)
        } else {
            // Get the download URL for image
            DispatchQueue.main.async {
                // Run UI Updates
                print(imageURL)  // output looks perfectly fine
                imageURL = URL(string: url!.absoluteString) // This is where the problem is
                completionBlock(imageURL)
            }
        }
    }
}

您的代码有什么问题?

imageRef.downloadURL {和DispatchQueue.main.async {都是异步执行的。因此return imageURL甚至在任何这些块完成执行之前就会被执行:)

解决方案:

解决方案1:

你可以使用闭包:)你可以接受一个块/闭包作为你的函数参数,并在你得到imageURL时异步执行它:)

解决方案2:

您可以使用Protocol / delegate模式并调用委托方法并将imageURL传递给委托:)

解决方案3 :(不建议)

如果你想不惜任何代价返回(虽然不建议)使用信号量并阻止线程的执行,一旦你有了imageURL释放信号量并执行return语句:)