iOSアプリ開発

SwiftでJSONデータを使いやすくする!Codableの使い方

APIからデータを取得する時、JSONでデータを受け取ることがあるかと思います。JSONでデータを受け取った時、受け取り側でモデルに変換してデータを扱うことがあります。Swift 4から提供されているCodableを使うことでモデルへの変換が簡単にできます。

今回は、Codableについて紹介します。

Codableとは?

Swift 4から提供されているプロトコルの1つで、JSONからモデルへ変換するときのように異なるフォーマットへ変換するのをサポートするプロトコルです。API通信などで受け取ったJSONデータとモデルを相互変換するのに非常に役に立ちます。

検証環境

  • Xcode 10
  • QuickとNimbleを利用して検証

Codableを使ったモデルの実装

1. JSONをCodableを使ってモデルに変換する

今回は、Qiita APIのユーザーモデルを利用します。まずは、Requiredなプロパティをモデルに定義します。

import Foundation

struct User: Codable {
    let id: String
    let permanentId: String
    let profileImageUrl: String
    let itemsCount: Int
    let followeesCount: Int
    let followersCount: Int
}

Codableを使って変換するテストを書いて確認して見ます。

import Quick
import Nimble

class UserTest: QuickSpec {
    override func spec() {
        describe("Parsing json to User") {
            it("is success") {
                let data = """
                {
                    "id" : "yaotti",
                    "permanentId": 1,
                    "profileImageUrl": "https://goo.gl/kqfaHF",
                    "itemsCount": 300,
                    "followeesCount": 100,
                    "followersCount": 200,
                }
                """.data(using: .utf8)!

                let user = try! JSONDecoder().decode(User.self, from: data)
                
                dump(user)
                expect(user.id).to(equal("yaotti"))
                expect(user.permanentId).to(equal(1))
                expect(user.profileImageUrl).to(equal("https://goo.gl/kqfaHF"))
                expect(user.itemsCount).to(equal(300))
                expect(user.followeesCount).to(equal(100))
                expect(user.followersCount).to(equal(200))
            }
        }
    }
}

実行すると以下のように、JSONからユーザーモデルへ変換できています。

▿ sampleTests.User
  - id: "yaotti"
  - permanentId: 1
  - profileImageUrl: "https://goo.gl/kqfaHF"
  - itemsCount: 300
  - followeesCount: 100
  - followersCount: 200
  
Result
> Test Suite 'All tests' passed at 2018-10-13 18:21:49.367.
> Executed 1 test, with 0 failures (0 unexpected) in 6.263 (6.269) seconds

2. JSONキーをスネークケースに対応する

サンプルで書いているJSONデータのキーはキャメルケースになっています。しかし、APIで取得するプロパティのキーはスネークケースなのでスネークケースに修正します。

スネークケースで利用する場合は、CodingKeysに対応するキーを設定します。対応づけが必要ない場合は、キーは省略できます。

struct User: Codable {
    
    /* 中略 */
    
    enum CodingKeys: String, CodingKey {
        case id
        case permanentId = "permanent_id"
        case profileImageUrl = "profile_image_url"
        case itemsCount = "items_count"
        case followeesCount = "followees_count"
        case followersCount = "followers_count"
    }
}

テストのJSONデータも以下のように修正します。

let data = """
{
    "id" : "yaotti",
    "permanent_id": 1,
    "profile_image_url": "https://goo.gl/kqfaHF",
    "items_count": 300,
    "followees_count": 100,
    "followers_count": 200,
}
""".data(using: .utf8)!

先ほどと同様にテストを実行すると、以下のような結果になり成功します。

▿ sampleTests.User
  - id: "yaotti"
  - permanentId: 1
  - profileImageUrl: "https://goo.gl/kqfaHF"
  - itemsCount: 300
  - followeesCount: 100
  - followersCount: 200

Result
> Test Suite 'All tests' passed at 2018-10-13 18:34:14.015.
> Executed 1 test, with 0 failures (0 unexpected) in 5.543 (5.552) seconds

3. nullで渡ってくるケースにも対応する

APIを利用するとき、全ての値が必ず値を持っているとは限りません。その時は、Optionalを使って値をnilで保持できるようにしましょう。今回は、facebookIdを取得してみます。この値は、Facebookをリンクしていないと取得できません。

struct User: Codable {
    /* 中略 */
    /* Option */
    let facebookId: String?
    
    enum CodingKeys: String, CodingKey {
        /* 中略 */
        case facebookId = "facebook_id"
    }
}

データにfacebook_idを追加して、nullをセットするようにします。

let data = """
{
    ...
    "facebook_id": null
}
""".data(using: .utf8)!

/* 中略 */
expect(user.facebookId).to(beNil())

先ほどと同様にテストを実行すると、以下のような結果になり成功します。facebookIdにnilがセットされていますね。

▿ sampleTests.User
  - id: "yaotti"
  - permanentId: 1
  - profileImageUrl: "https://goo.gl/kqfaHF"
  - itemsCount: 300
  - followeesCount: 100
  - followersCount: 200
  - facebookId: nil

Result
> Test Suite 'All tests' passed at 2018-10-13 19:34:24.939.
> Executed 1 test, with 0 failures (0 unexpected) in 5.954 (5.959)

まとめ

Codableを使うことで、DictionaryやSwiftyJSONを使うといったことなくJSONデータを簡単に変換できるようになります。また、工夫をすれば特殊な変換するロジックを挟むこともできる様になります。Codableは非常に便利なのでおすすめです。

Pythonスクレイピングの導入と利用の注意ポイントPrev

スクレイピングでヘッダー情報を付与する方法とその目的Next

Related post

  1. テクノロジー

    簡単にサーバーを立てたい時におすすめのCloud Functins for Firebaseを紹介!…

    ウェブサービスやアプリで使うからサーバーを立てたいけど、サーバーを立ち…

  2. テクノロジー

    iOSアプリ開発が簡単にできるStoryboard入門

    iOSアプリを開発しようとXcodeをダウンロードしてプロジェクト作成…

  3. テクノロジー

    iOSアプリ開発者になる人が読んでいる12の本を紹介 2020年版

    「iOSエンジニアになるために、どんな本を読んで勉強すれば良いですか?…

  4. swiftui

    iOSアプリ開発

    StateとObservableを使ってSwiftUIのビューを変更する方法

    SwiftUIフレームワークを使っているとStateやObserved…

  5. テクノロジー

    CSSによるセンタリングの方法と注意点についてのまとめ

    HTMLとかCSSの勉強を始めると、divやsectionなどで作った…

  6. テクノロジー

    ReactiveXとは?RxJSの入門と導入手順

    Rx (Reactive Extension)とはここ数年で話題になっ…

PAGE TOP