LoginSignup
4
5

More than 5 years have passed since last update.

Decodableの使い方

Posted at

この記事ではCodableを使ったことがない人向けに、簡単なJSONをパースするサンプルコードを説明します。

※プロダクションではtry!せずにguardなどで安全に処理してください

Decodableとは

JSONを対応する型に変換する仕組み

使い方

sample.json
{
    "name": "Mario",
    "height": 165
}
Model
struct Model: Decodable {
    let name: String
    let height: Int
}

sample.jsonをModel型に変換する場合

let model = try! JSONDecoder().decode(Model.self, from: json)

配列が含まれている場合

sample.json
{
    "name": "Mario",
    "height": 165,
    "likes": ["Kinoko", "1UpKinoko", "FireFlower"]
}
Model
struct Model: Decodable {
    let name: String
    let height: Int
    let likes: [String]
}

Enumに変換したい場合

sample.json
{
    "name": "Mario",
    "height": 165,
    "likes": ["Kinoko", "1UpKinoko", "FireFlower"],
    "bloodType": "B"
}
Model
struct Model: Decodable {
    let name: String
    let height: Int
    let likes: [String]
    let bloodType: BloodType

    enum BloodType: String, Decodable {
        case a = "A"
        case b = "B"
        case o = "C"
        case ab = "AB"
    }
}

配列の要素がオブジェクトの場合

sample.json
{
    "name": "Mario",
    "height": 165,
    "likes": ["Kinoko", "1UpKinoko", "FireFlower"],
    "bloodType": "B",
    "enemy": [
        {
            "name": "Kuribo-"
        },
        {
            "name": "Nokonoko"
        },
        {
            "name": "Patapata"
        }
    ]
}
Model
struct Model: Decodable {
    let name: String
    let height: Int
    let likes: [String]
    let bloodType: BloodType
    let enemy: [Enemy]

    enum BloodType: String, Decodable {
        case a = "A"
        case b = "B"
        case o = "C"
        case ab = "AB"
    }

    struct Enemy: Decodable {
        let name: String
    }
}

enemyの配列部分だけパース時に取り出して欲しい場合

sample.json
{
    "name": "Mario",
    "height": 165,
    "likes": ["Kinoko", "1UpKinoko", "FireFlower"],
    "bloodType": "B",
    "enemy": [
        {
            "name": "Kuribo-"
        },
        {
            "name": "Nokonoko"
        },
        {
            "name": "Patapata"
        }
    ]
}
Model
struct Model: Decodable {
    let enemy: [Enemy]

    enum BloodType: String, Decodable {
        case a = "A"
        case b = "B"
        case o = "C"
        case ab = "AB"
    }

    struct Enemy: Decodable {
        let name: String
    }

    enum CodingKeys: CodingKey {
        case name
        case height
        case likes
        case bloodType
        case enemy
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        self.enemy = try values.decode([Enemy].self, forKey: .enemy)
    }
}

ここの自作Decoderの手順です
1, JSONがCodingKeysのキー名で全て正常に取り出せるか
2, 取り出せたものに対してキー名enemyでアクセスしそのバリューが[Enemy]型で取り出せるか
3, 正常に[Enemy]型で取り出せたら自分のプロパティを初期化してパース成功!!

4
5
0

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
4
5