はじめに
先日、初めてAlamofireを使ってAPIのコール処理を実装しました。
せっかくなので、標準の URLSession.dataTask
メソッドを使った場合と書き比べてみます。
環境
- Swift:5.0.1
- Alamofire:4.8.2
例
以下のAPIからディズニーランドの住所を取得し、構造体に格納します。
http://zipcloud.ibsnet.co.jp/api/search?zipcode=2790031
レスポンス
{
"message": null,
"results": [
{
"address1": "千葉県",
"address2": "浦安市",
"address3": "舞浜",
"kana1": "チバケン",
"kana2": "ウラヤスシ",
"kana3": "マイハマ",
"prefcode": "12",
"zipcode": "2790031"
}
],
"status": 200
}
実装を比べてみる
共通処理
構造体は Decodable
を使って実装しました。
レスポンスの一部のみ抜粋しています。
Address.swift
struct Address: Decodable {
var results: [Result]
struct Result: Decodable {
var address1: String
var address2: String
var address3: String
var kana1: String
var kana2: String
var kana3: String
}
}
住所の取得は getAddress
メソッドを呼び出すことにします。
住所の取得
getAddress(zipCode: "2790031")
標準
標準の URLSession.dataTask
メソッドを使った実装です。
import Foundation
// ...
private var address: Address?
private func getAddress(zipCode: String) {
let baseUrlString = "http://zipcloud.ibsnet.co.jp"
let searchPath = "/api/search"
let searchUrl = URL(string: baseUrlString + searchPath)!
guard var components = URLComponents(url: searchUrl, resolvingAgainstBaseURL: searchUrl.baseURL != nil) else {
return
}
components.queryItems = [
.init(name: "zipcode", value: zipCode),
] + (components.queryItems ?? [])
var request = URLRequest(url: components.url!)
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Error: \(error)")
return
}
guard let data = data else {
return
}
do {
self.address = try JSONDecoder().decode(Address.self, from: data)
} catch let error {
print("Error: \(error)")
}
}.resume()
}
Alamofire
続いて、Alamofireを使った実装です。
import Alamofire
// ...
private var address: Address?
private func getAddress(zipCode: String) {
let baseUrlString = "http://zipcloud.ibsnet.co.jp"
let searchPath = "/api/search"
let parameters: [String: Any] = ["zipcode": zipCode]
let headers: HTTPHeaders = ["Content-Type": "application/json"]
Alamofire.request(baseUrlString + searchPath, method: .get, parameters: parameters, encoding: URLEncoding(destination: .queryString), headers: headers).responseJSON { response in
guard let data = response.data else {
return
}
do {
self.address = try JSONDecoder().decode(Address.self, from: data)
} catch let error {
print("Error: \(error)")
}
}
}
おわりに
標準と比べてAlamofireの方がAPIコール処理を簡潔に実装できました。
ただ、標準をそのまま使うことはあまりなく、自前でラップすればもう少し簡潔に書くことができます。
もっといい実装やおすすめのラップ方法があれば、ご教授いただけると嬉しいです。