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は非常に便利なのでおすすめです。

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

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

Related post

  1. dark-mode

    iOSアプリ開発

    iOSアプリでダークモードに対応する様々な方法

    アプリやOSのUIを全体的に黒を基調としたデザインにする機能で、201…

  2. iOSアプリ開発

    DispatchQueueを使って容量のあるファイルをダウンロードする方法

    アプリなどで画像のようなファイルデータをダウンロードすることはよくあり…

  3. swiftui

    iOSアプリ開発

    初心者でもiOSアプリ開発ができるSwiftUIを触ってみよう

    iPhoneアプリ作ってみたいけど「アプリ開発って難しそう」「作り方が…

  4. debugging

    iOSアプリ開発

    iOSアプリ開発で初心者が覚えるべきデバッグ3つの手法

    iOS(iPhone)アプリを作り始めるといろんな不具合やエラーに悩ま…

  5. hstack-vstack

    iOSアプリ開発

    SwiftUIでレイアウトを簡単にするHStackとVStackの使い方

    初めてSwiftUIを使ってアプリ開発するとき、まだ慣れていなくてレイ…

  6. iOSアプリ開発

    iOSアプリ初心者が覚えておきたい10のUIクラス

    iOSアプリを開発したいけど、最初は何を知っていたら開発できるのかわか…

PAGE TOP