ローソンデジタルイノベーション(LDI)のiOS/Android開発マネージャーの阪口です。
開発しているアプリのAPI通信処理は、Alamofire を利用して実装しています。 通信処理部分をSwift Concurrency に対応したため、今回はどのように実装したか紹介します!
通信のTimeoutの設定
Timeoutの設定は Alamofire の Sessionで設定する必要があります。
公式ドキュメント
では、 AF.request
を利用してSwift Concurrency のコードの実装例が紹介されていますが、Alamofire の Session でも Swift Concurrency を利用することは可能です。
そのため、Timeoutの設定は引き続きAlamofire の Sessionで設定しています。
/// API通信の共通処理 struct APIClient { let apiSession: Session init(apiSession: Session = Session(), connectionTimeout: TimeInterval = 10, resourceTimeout: TimeInterval = 20 ) { self.apiSession = apiSession self.apiSession.session.configuration.timeoutIntervalForRequest = connectionTimeout // リクエストがサーバーに到達するまでの時間 self.apiSession.session.configuration.timeoutIntervalForResource = resourceTimeout // リクエストが完全に完了するまでの全体的な時間 } ... }
リクエスト処理の書き方
リクエストは、Alamofire の Session.request の呼び出しで
serializingDataを利用することで、Swift Concurrency に対応している
- response
- result
- value
へアクセスすることができます。
今回は response 利用してリクエスト処理を実装しました。
struct APIClient { ... func request<Response: APIResponse>(request: URLRequest) async throws -> Response { let response = await apiSession .request(request) .validate(statusCode: 200 ..< 400) .serializingData() .response // async に対応したプロパティ switch response.result { case let .success(data): // statusCode が 200 ..< 400 の範囲のとき return try handleSuccess(request: request, data: data) case let .failure(rawError): // ネットワークエラーや、statusCode が 200 ..< 400 の範囲外のとき let error = handleError(request: request, response: response) throw error } } }
serializingData の部分を serializingDecodable に変えて、serializingDecodable の引数で渡したクラスへレスポンスのJSONを簡単にパースすることもできそうです。
最後に
Alamofire の Session を利用した、Swift Concurrency のコード紹介例が見当たらなかったため、今回記事で紹介しました!
Swift Concurrency を利用することで、ネストが深くならず可読性も上がりとても良いですね。
LDIに興味が出てきた方、または応援いただける方は是非「読者になる」で応援していただけますと嬉しいです!