Swift完成处理程序 - 转义尾随闭包

时间:2017-10-20 20:41:34

标签: swift function escaping swift4 completionhandler

我现在已经阅读了很多关于带闭包,尾随闭包和转义函数的快速函数的文章。他们似乎都给出了足够不同的例子,以至于我不理解我对自己的功能做错了什么。

我的主要问题是如何执行尾随闭包功能。

我已创建此功能以将图片上传到firebase。它需要两个输入,并且应该返回一个字符串(imageURL)。我相信这个功能还可以。

func uploadImageToFirebaseAndReturnImageURL(directory: String, image: UIImage!, handler: @escaping(_ imageURL: (ImageURL))  -> ()) {
    let imageName = NSUUID().uuidString // create unique image name

    if let uploadData = UIImagePNGRepresentation(image) {
        DB_STORE.child(directory).putData(uploadData, metadata: nil, completion: { (metadata, error) in

            if error != nil {
                print(error)
                return
            }

            if let profileImageUrl = metadata?.downloadURL()?.absoluteString {
                let d = ImageURL(imageURL: profileImageUrl)
                handler (d)             
            }
            return

        })
    }
}

我的问题是如何在处理程序时正确执行此功能。 我想首先执行该函数然后在完成时我想获取imageURL并将此变量用于另一个嵌套函数,该函数将此变量(String)上载到firebase数据库中。

uploadImageToFirebaseAndReturnImageURL(directory: "profileImage", image: selectedImageFromPicker!, handler: { imageURL in
    guard let uid = Auth.auth().currentUser.uid else { print("User is not logged in"); return }
    DataService.instance.updateUserWithProfileImageURL(uid: uid, imageURL: imageURL)
    print("")
}

我做错了什么?

1 个答案:

答案 0 :(得分:1)

要传递 trailing closure ,您需要结束/关闭函数调用省略闭包参数标签。例如:

func foo(first: Int, second: Int, handler: (Int) -> Void) {
    ...
}

调用语法:

foo(first: 10, second: 20) { result in
    /* trailing closure body */
}

顺便说一下,你应该只需要来自handler的{​​{1}}参数声明:

handler: @escaping (_ imageURL: (ImageURL)) -> ()

到此:

handler: @escaping (ImageURL) -> Void

使用Void()是风格问题,因为它们在逻辑上是相同的。我更喜欢前者;)