【问题标题】:How to refactor Swift API call to use Swift 5.5 async/await?如何重构 Swift API 调用以使用 Swift 5.5 async/await?
【发布时间】:2021-10-02 12:30:22
【问题描述】:

我想重构一些 API 调用以在我的 SwiftUI 项目中使用 Swift 5.5 的新 async/await。但是,我不清楚如何替换或容纳完成。

这是我要重构的示例函数:

 static func getBooks(completion: @escaping ([Book]?) -> Void) {
    let request = getRequest(suffix: "books")
    
    URLSession.shared.dataTask(with: request) { data, response, error in
        if let error = error {
            fatalError("Error: \(error)")
        }
        if let data = data {
            if let books = try? JSONDecoder().decode([Book].self, from: data) {
                DispatchQueue.main.async {
                    print("books.count: \(books.count)")
                    completion(books)
                }
                return
            } else {
                fatalError("Unable to decode JSON")
            }
        } else {
            fatalError("Data is nil")
        }
    }.resume()
}

我相信新的函数签名应该是这样的:

static func getBooks() async throws -> ([Book]?) {
   // ...
}

但是,我不知道如何处理 URLSession.shared.dataTaskDispatchQueue.main.asynccompletion 等。

有人知道新的函数体应该是什么样子吗?

谢谢

【问题讨论】:

标签: swift macos async-await swiftui


【解决方案1】:
func getBooks() async throws -> [Book] {
    let (data, _) = try await URLSession.shared.data(for: request)
    return try JSONDecoder().decode([Book].self, from: data)
}

如果请求失败并且无法解码响应,则会抛出此错误。由于该函数被标记为 throwing,因此调用函数必须处理引发的错误。

您不需要将返回的[Book] 声明为可选,因为它要么返回一个诚实的数组,要么抛出一个错误。

在您的附加代码中,您必须在主队列上调用完成处理程序,因为您是从请求的完成块中调用它。您无需在此处执行此操作。

【讨论】:

    猜你喜欢
    • 2021-10-15
    • 2021-07-26
    • 2021-09-19
    • 1970-01-01
    • 2021-12-01
    • 2022-01-07
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多