iOS SDK 学习笔记02:async / await

http://img2.58codes.com/2024/20158406nd257ZrYEs.jpg


在阅读 Apple Education 出版的 Develop in Swift Data Collections 这本书时,关于 URLSession 部分,注意到在 Swift 5.5 之后引入新的 async / await API,因此想简单做个笔记。而本文主要目的是比较新旧不同的实作方式,对于错误处理就先简单处理。如果有理解错误,还烦请指正,谢谢。内容主要改编书中提到的例子。

先定义取得的资料 Struct
enum PhotoInfoError: Error, LocalizedError {    case itemNotFound}struct PhotoInfo: Codable {    var title: String    var description: String    var url: URL    var copyright: String?    enum CodingKeys: String, CodingKey {        case title        case description = "explanation"        case url        case copyright    }}
使用 async / await
func fetchPhotoInfoNew() async throws -> PhotoInfo {    let url = URL(string: "https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY")!    let session = URLSession(configuration: .default)    let (data, response) = try await session.data(from: url)    guard let httpResponse = response as? HTTPURLResponse,          httpResponse.statusCode == 200 else {        throw PhotoInfoError.itemNotFound    }    let jsonDecoder = JSONDecoder()    let photoInfo = try jsonDecoder.decode(PhotoInfo.self, from: data)    return(photoInfo)}Task {    do {        let photoInfo = try await fetchPhotoInfoNew()        print("Successfully fetched PhotoInfo: \(photoInfo)")    } catch {        print("Fetch PhotoInfo failed with error: \(error)")    }}

用 async 关键字宣告 fetchPhotoInfoNew() 为非同步函式,并使用 await 关键字执行 URLSession 的 data(from:) 方法获取 URL 的回应。当回应的 HTTP 状态码为 200 时,会将数据解码为 PhotoInfo 并返回该实例。Task 这个实例则用于执行非同步函数 fetchPhotoInfoNew(),印出 photoInfo 的值或处理错误。

而在这之前的作法为使用 URLSession.dataTask(with: URLRequest, completionHandler: (Data?, URLResponse?, Error?) -> Void) { ... }

当 data task 完成时,在 completionHandler 这个 closure 里处理 response、data,或者 error 的状况。也就是说,这个 closure 是当 task 完成时会被自动呼叫,并透过这个 closure 回传结果,以便开发者进一步处理。程式码如下:

使用 URLSession.dataTask
func fetchPhotoInfoOld() {    if let url = URL(string: "https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY") {        let session = URLSession(configuration: .default)        let task = session.dataTask(with: url) { data, response, error in            guard let httpResponse = response as? HTTPURLResponse,                  httpResponse.statusCode == 200 else {                return            }            guard let safeData = data else {                print("No data")                return            }            do {                let jsonDecoder = JSONDecoder()                let photoInfo = try jsonDecoder.decode(PhotoInfo.self, from: safeData)                print("Successfully fetched PhotoInfo: \(photoInfo)")            } catch {                print("Failed to decode PhotoInfo: \(error)")            }        }        task.resume()    }    }fetchPhotoInfoOld()

使用 async / await 的好处是避免使用那一串 closure,让程式码变得较为简洁。


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章