Swiftui 异步/等待与 Firebase

Swiftui async / await with Firebase

我正在尝试从数据库中取出最后一个 AppVersion 文档!

我做错了什么?

func getLastAppVertion() async throws -> ApplicationVersion {
            firebase.collection("ApplicationVersion")
                    .order(by: "major")
                    .order(by: "minor")
                    .order(by: "patch")
                    .limit(to: 1)
                    .getDocuments { (querySnapshot, error) in
                        if let error = error {
                            throw AppError.networkerror
                        } else {
                            for document in querySnapshot!.documents {
                                let major = document.data()["major"] as? Int ?? 7
                                let minor = document.data()["minor"] as? Int ?? 15
                                let patch = document.data()["patch"] as? Int ?? 0
                                let sendAppVersion = ApplicationVersion(major: major,
                                                                        minor: minor,
                                                                        patch: patch,
                                                                        device: .iPhone)
                                return sendAppVersion
                        }
                    }
                }
    }

您将旧的异步调用与新的并发混合在一起。

您需要使用 withUnsafeThrowingContinuation 进行转换,如下所示:

func getLastAppVertion() async throws -> Float {
    try withUnsafeThrowingContinuation { continuation in
        firebase.collection("ApplicationVersion")
            .order(by: "major")
            .order(by: "minor")
            .order(by: "patch")
            .limit(to: 1)
            .getDocuments { (querySnapshot, error) in
                if let error = error {
                    continuation.resume(throwing: AppError.networkerror)
                    return
                } else {
                    for document in querySnapshot!.documents {
                        let major = document.data()["major"] as? Int ?? 7
                        let minor = document.data()["minor"] as? Int ?? 15
                        let patch = document.data()["patch"] as? Int ?? 0
                        let sendAppVersion = ApplicationVersion(major: major,
                                                                minor: minor,
                                                                patch: patch,
                                                                device: .iPhone)
                        continuation.resume(returning: 1)
                        // not sure why you're using a for loop and returning the first value here
                        return
                    }
                }
            }
    }
}

我建议您从 Swift concurrency: Update a sample app 和其他关于 Swift 并发的 WWDC 讨论开始,以了解如何使用它。

您正在使用完成处理程序调用 getDocuments

您不能将 Swift 结构化并发 async/await 直接与 getDocuments / 完成处理程序混合。 async/await 和 completion handler 是相反的。

关于你的完成处理程序的一切都是错误的。您不能从完成处理程序中抛出。您不能 return 来自完成处理程序的任何内容。这就是 async/await 的重点。那就是 为什么 async/await 取代完成处理程序。

要围绕完成处理程序调用包装 async/await,您必须使用 withUnsafeThrowingContinuation