概要
async / awaitがしたい!
こんな感じでAlamofireを使用している処理を書き直したい!
final class WeatherAPI {
func get(success: @escaping ((WeatherForecastResponse) -> Void), failure: @escaping ((Error) -> Void)) {
AF.request("https://www.jma.go.jp/bosai/forecast/data/overview_forecast/130000.json").response { response in
switch response.result {
case .success(let element):
do {
success(try JSONDecoder().decode(WeatherForecastResponse.self, from: element!))
} catch let error {
failure(error)
}
case .failure(let error):
failure(error)
}
}
}
}
struct WeatherForecastResponse: Codable {
var publishingOffice: String
var reportDatetime: String
var targetArea: String
var headlineText: String
var text: String
init(publishingOffice: String, reportDatetime: String, targetArea: String, headlineText: String, text: String) {
self.publishingOffice = publishingOffice
self.reportDatetime = reportDatetime
self.targetArea = targetArea
self.headlineText = headlineText
self.text = text
}
}
やってみた。
withCheckedThrowingContinuationを使用すればできそうだぞ!
https://developer.apple.com/documentation/swift/3814989-withcheckedthrowingcontinuation
final class WeatherAPI {
func get() async throws -> WeatherForecastResponse {
try await withCheckedThrowingContinuation { continuation in
AF.request("https://www.jma.go.jp/bosai/forecast/data/overview_forecast/130000.json").response { response in
switch response.result {
case .success(let element):
do {
continuation.resume(returning: try JSONDecoder().decode(WeatherForecastResponse.self, from: element!))
} catch {
continuation.resume(throwing: error)
}
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
}
毎回こんなこと書いてるの面倒なので、AlamofireのDataRequestを拡張したのがこれ。
Alamofireの呼び出し処理なんて、アプリごとには多少のカスタマイズはあるけど、APIごとに大きく変わらないからこれで良さそう。
final class WeatherAPI {
func get() async throws -> WeatherForecastResponse {
return try await AF.request(""https://www.jma.go.jp/bosai/forecast/data/overview_forecast/130000.json"").response()
}
}
extension DataRequest {
func response<T>() async throws -> T where T : Decodable {
try await withCheckedThrowingContinuation { continuation in
self.response { response in
switch response.result {
case .success(let element):
do {
continuation.resume(returning: try JSONDecoder().decode(T.self, from: element!))
} catch {
continuation.resume(throwing: error)
}
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
}