Blog スタッフブログ

Swift システム開発

[Swift]CodableによるAPI連携処理の基本

Swift

こんにちは、株式会社MIXシステム開発担当のBloomです。

早速本題のCodableによるAPI連携の基本的な書き方について、

お仕事の中で得た知見を共有させていただきたいと思います。

Codableとは

CodableはSwift3以降で利用できる、JSON文字列をSwiftのクラスにエンコード/デコードができるプロトコルです。

Codableの公式ドキュメントはこちら

Codableを継承したクラスや構造体を定義しておくことで、JSON文字列のパース処理を自分で書かなくても自動的に変換できるようになります。下記に基本的なCodableを継承した構造体の例を掲載します。

struct DataResponse: Codable {
    let message: String
    let code: String
    let count: Int
    let dictionary: [Int: String]
    let array: [Int]
    let number: Double
    let details: [DataResponseDetailObject]
}
// 入れ子にも対応しています。
struct DataResponseDetailObject: Codable {
    let detail: String
}

この構造体を定義することで、下記形式のJSON文字列をパースすることができます。

{"message": "quick brown fox ...",
 "code": "200",
 "count": 10,
 "dictionary": {1: "first column", 
                2: "second column", ...},
 "array": {1, 2, 3, ...}
 "number": 3.141,
 "details": {"detail": "foo", "detail": "bar", ...}
}

「”200″」のようなダブルクォートで囲われた数値はString型として認識されるため、デコードに失敗します。API実装側の型の定義には注意してください。

Alamofireで利用する

では、上の構造体を利用してAlamofireによりAPIをコールしてみましょう。

Alamofireについてのドキュメントはこちら

    class func getData(handler:@escaping (DataResponse?) -> Void) {
        let apiUrl = URL(string: "https://example.com/api")!
        let headers = ["Content-Type":"application/json; charset=UTF-8",
                       "X-Requested-With" : "XMLHttpRequest",
                       "Accept": "application/json"]
        
        Alamofire.request(apiUrl,
                          method: .get,
                          parameters: nil,
                          encoding: JSONEncoding.default,
                          headers: headers).responseJSON { response in
            if let result = response.result.value as? [String: Any] {
                do {
                    let responseJsonData = try JSONSerialization.data(withJSONObject: result)
                    let decoder = JSONDecoder()
                    let dataResponse = try? decoder.decode(DataResponse.self, from: responseJsonData)
                    handler(dataResponse)
                }
                catch let e {
                    print(e.localizedDescription)
                    handler(nil)
                }
            }
            else {
                print(response.error ?? "nil error")
                handler(nil)
            }
        }
    }

これだけでAPIから受け取ったJSONデータを簡単に処理できるようになりました。良かったですね。

参考文献

Encoding and Decoding Custom Types – Apple Developer Documentation

Alamofire – Github