6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Alamofireでもasync / awaitがしたい!

Last updated at Posted at 2022-04-26

概要

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)
                }
            }
        }
    }
}

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?