【swift】JSONデータからオブジェクトにするのにCodableを使うとかなり便利

もくじ

こんにちは。iOSをメインに開発しているロッキーカナイです。

Swiftのバージョンが4になってから大分経ちますが、Swift4のFoundationに採用されているCodableプロトコルがかなり便利なのでご紹介します。

これまでは、JSONをパースして、Dictionaryのキーを指定してデータクラスに代入するような流れを実装していたと思うのですが、Codableを使用することで勝手にマッピングしてくれちゃうんです。

Codableを使用しない場合の例

JSON

{
	"blog": "イーガオブログ",
	"title": "Codable",
	"description": "猫最高",
	"status": 1
}

データを入れる構造体

struct Test {
    let blog: String?
    let title: String?
    let description: String?
    let status: Int?
}

JSONデータから構造体へ

do {
    // JSONパース
    guard
        let data = try JSONSerialization.jsonObject(with: jsonData) as? Dictionary<String, Any> else {
            print("json convert failed")
        return
    }

    // Test構造体
    var test = Test()
    test.blog = data["blog"] as? String
    test.title = data["title"] as? String
    test.description = data["description"] as? String
    test.status = data["status"] as? Int
    print(test)

} catch {
    print("error:", error.localizedDescription)
}

実際のアプリ開発の現場では、WebAPIを用いてサーバから取得する際に、もっとデータが多くなると思うので、結果的に膨大なコード量となりえます。

Codableを使用する

使用例

JSON

{
	"blog": "イーガオブログ",
	"title": "Codable",
	"description": "猫最高",
	"status": 1
}

データを入れる構造体

struct Test: Codable {
    let blog: String
    let title: String
    let description: String
    let status: Int
}

JSONデータから構造体へ

let decoder: JSONDecoder = JSONDecoder()
do {
    let json: Test = try decoder.decode(Test.self, from: jsonData)
    print(json)
    
} catch {
    print("error:", error.localizedDescription)
}

はい。これだけです。

かなりすっきりし見やすくなったと思います。

例 ネストしているJSONデータ時

JSONデータがネストしている場合はどうなるのでしょうか?

Codableならネストも簡単です。

JSON

{
	"blog": "イーガオブログ",
	"title": "Codable",
	"description": "猫最高",
	"status": 1,
	"url": {
		"url": "https://",
		"thumbnailUrl": "https://"
	}
}

データを入れる構造体

struct Test: Codable {
    let blog: String
    let title: String
    let description: String
    let status: Int
    let url: Test2
    
    struct Test2: Codable {
        let url: String
        let thumbnailUrl: String
    }
}

JSONデータから構造体へ

let decoder: JSONDecoder = JSONDecoder()
do {
    let json: Test = try decoder.decode(Test.self, from: jsonData)
    print(json)
    
} catch {
    print("error:", error.localizedDescription)
}

例 JSONのキーがキャメルケースの場合など、構造体のプロパティ名が異なる場合

ここまでの例でお判りかと思いますが、マッピング時にプロパティ名と一致している必要があります。ですが、JSONのキーってキャメルケースの場合が多いです。

プロパティ名をキャメルケースにするのは気持ち悪いですよね。これもCodableならCodingKeysで対応できます。

JSON

{
	"comment": "ハロー"
}

データを入れる構造体

struct Test: Codable {
    let text: String
    
    private enum CodingKeys: String, CodingKey {
        case text = "comment"
    }
}

JSONデータから構造体へ

let decoder: JSONDecoder = JSONDecoder()
do {
    let json: Test = try decoder.decode(Test.self, from: jsonData)
    print(json)
    
} catch {
    print("error:", error.localizedDescription)
}

まとめ

いかがでしたでしょうか?

Codableの登場で、かなりコードがすっきりしたのではないでしょうか?

コードが少ないということはバグの発生も少なくなると思うので、いい事ずくめではないのでしょうか?

ではでは〜良いSwiftライフを〜

関連する記事

もっと見る