LoginSignup
78
63

標準とAlamofireでAPIコール処理を書き比べてみる(Swift)

Last updated at Posted at 2019-07-04

はじめに

先日、初めて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コール処理を簡潔に実装できました。
ただ、標準をそのまま使うことはあまりなく、自前でラップすればもう少し簡潔に書くことができます。

もっといい実装やおすすめのラップ方法があれば、ご教授いただけると嬉しいです。

78
63
4

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
78
63