Applying async/await was not hard. It just has some difficulties that I didn't expect.
Comparing Code Styles
I had already use AwaitKit
to program async before Xcode 13. The async/await codes looked similar. Comparing:
// AwaitKit version
private func usersShow() throws {
let weiboAPI = WeiboAPIType.users_show.weiboAPI
let (data, reponse) = try `await`(URLSession.shared.dataTask(.promise, with: weiboAPI.urlRequest))
let httpURLResponse = reponse as! HTTPURLResponse
if (200..<300).contains(httpURLResponse.statusCode) {
weiboAPI.saveStatus(from: data)
} else {
throw Result.weiboError(httpURLResponse.statusCode, data)
}
}
// Xcode 13 version
@available(iOS 15.0, *)
private func usersShow() async throws {
let weiboAPI = WeiboAPIType.users_show.weiboAPI
let (data, reponse) = try await URLSession.shared.data(for: weiboAPI.urlRequest)
let httpURLResponse = reponse as! HTTPURLResponse
if (200..<300).contains(httpURLResponse.statusCode) {
weiboAPI.saveStatus(from: data)
} else {
throw Result.weiboError(httpURLResponse.statusCode, data)
}
}
Only the definition line and `let (data, response) line are different. So refactoring old codes are easy.
Issues
Unlike AwaitKit
, async/await in Xcode 13 sorts code to be async and sync. But what if you want to use an async function to be run in a closure that not allowed async to run?
The answer is to provide the async version functions. Like func data(from url: URL, delegate: URLSessionTaskDelegate? = nil) async throws -> (Data, URLResponse)
for func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask
. However, not all API currently are provided the counterpart. More will be come.
Apple provides sync and async versions of functions, but another problem shows. As async only works in IOS 15, so we may want the compiler to run the async version in iOS 15 and run the sync version in other prior iOS.
The compiler doesn't allow this feature. As somehow the compiler considers the async and sync versions are conflict to use together. So we should wait until the Concurrency is backwards to iOS 13.
References