[iOS][Alamofire] RequestAdapterを使用して、APIリクエスト前に任意の処理を実行する
はじめに
こんにちは。モバイル事業部の平屋です。
HTTPネットワーキングライブラリAlamofireにはRequestAdapterという仕組みがあり、リクエスト前に任意の処理を実行することができます。例えば、以下の処理を共通処理として追加できます。
- リクエストにAuthorizationヘッダーを追加する
本記事ではこのRequestAdapterの使い方を解説します。
検証環境
- macOS Monterey 12.2
- Xcode Version 13.1
(1) RequestAdapterを実装する
任意のクラスをRequestAdapter
プロトコルに適合させ、adapt(_:session:completion:)
を実装します。
このメソッド内では、引数で渡されたURLRequest
に対して任意の処理を行い、completion
を呼びます。
以下の例では、リクエストにAuthorizationヘッダーを追加しています。
class Adapter: RequestAdapter { let accessToken = "xxxxx" func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) { var urlRequest = urlRequest // Authorizationヘッダーを追加 urlRequest.headers.add(.authorization(bearerToken: accessToken)) // 処理を行った結果を渡す completion(.success(urlRequest)) } }
(2) RequestAdapterを使う
(1)で実装したRequestAdapterを使うには、以下を実装します。
- (2-1)
Adapter
からInterceptor
を生成 - (2-2)
Interceptor
と共にSession
を生成 - (2-3)
Session
を使ってリクエストを実行
class ViewController: UIViewController { let session: Session = { // (2-1) let interceptor = Interceptor(adapters: [Adapter()]) // (2-2) let session = Session(interceptor: interceptor) return session }() override func viewDidLoad() { super.viewDidLoad() // (2-3) let request = try! URLRequest(url: "https://httpbin.org/get", method: .get) session.request(request).responseDecodable(of: Response.self) { response in switch response.result { case .success(let res): print("res:", res) case .failure(let error): print("error:", error) } } } } struct Response: Decodable { let headers: [String: String] let origin: String let url: String } extension Response: CustomDebugStringConvertible { var debugDescription: String { "headers: \(headers), origin:\(origin), url:\(url)" } }
(3) 動作確認
今回はhttps://httpbin.org/を使って動作確認しました。リクエスト内容をそのまま返してくれるエンドポイント(/get)などがあります。(Alamofire付属のサンプルコードで使われていました)
RequestAdapterを使った場合
RequestAdapter
を使ったサンプルコードを実行すると以下のレスポンスを取得できました。(Authorizationヘッダーが入っている)
headers: [ "Accept-Encoding": "br;q=1.0, gzip;q=0.9, deflate;q=0.8", "Host": "httpbin.org", "Authorization": "Bearer xxxxx", "Accept-Language": "en;q=1.0, ja-US;q=0.9" ... ], ...
RequestAdapterを使わない場合
また、RequestAdapter
を使わないようにサンプルコードを修正すると、
class ViewController: UIViewController { let session = Session() // ... }
以下のレスポンスを取得できました。(Authorizationヘッダーが入っていない)
headers: [ "Accept-Encoding": "br;q=1.0, gzip;q=0.9, deflate;q=0.8", "Host": "httpbin.org", "Accept-Language": "en;q=1.0, ja-US;q=0.9" ... ], ...