swift - 如何重构 Swift API 调用以使用 Swift 5.5 async/await?

标签 swift macos async-await swiftui

我想重构一些 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 等.

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

谢谢

最佳答案

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

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

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

在附加代码中,您必须在主队列上调用完成处理程序,因为您是从请求的完成 block 中调用它的。您不需要在这里这样做。

关于swift - 如何重构 Swift API 调用以使用 Swift 5.5 async/await?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68532042/

相关文章:

ios - 如何快速检查设备的互联网连接是否不佳

ios - 如何将 Mailchimp api 集成到我的 iOS Swift 应用程序中

macos - 在 Mac 上的 Google 表格中对单元格应用绝对引用的快捷方式是什么?

javascript - 如何等待数据有希望到来?

swift - 类属性 'current' 在异步上下文中不可用; Thread.current 不能在异步上下文中使用。这是 Swift 6 中的一个错误

node.js - nodejs - 在 for 循环结束后返回 Promise

ios - 循环引用,Obj-C -> Swift,Swift -> Obj-C

ios - 设置图像后,UIImageView 调整为奇怪的尺寸

c++ - Mac OS 中的 BLAS/LAPACK 和原来的 BLAS/LAPACK 有什么区别(如果有的话)?

java - 使用 Ghost4j 示例代码删除 Java Temp 文件时出错