Understand how to use Swift's JSON Decoder in 3 minutes

I want to make an app with Swift as pure as possible.

I don't want to include the library as much as possible! Have you ever thought so?

As a starting point, replacing SwiftyJson used for JSON decoding with pure Swift had only merit, so I will write it down here. Let's decode json with a standard Swift function called JSONDecoder.

Basic usage of JSON Decoder

1. Inherit Decodable to struct.

It's a great thing that makes struct / class decodable just by inheriting it.

import Foundation

struct User: Decodable {
  var name: String
  var age: Int
}

2. Convert json to Data.


let json = """
{
  "name": "Bob",
  "age": 20,
}
"""
let jsonData = json.data(using: .utf8)!

3. Decode with JSON Decoder.


let user = try JSONDecoder().decode(User.self, from: jsonData)

that's all. In struct, json is stored in struct. It's simple and easy to use.


print(user.name) // Bob
print(user.age) // 20

Fetch data from json in an array

Of course, you can also decode JSON whose root is an array. Also, if there is a key applied to json, it is expressed as an optional type.


import Foundation

let json = """
[
    {
        "name": "Bob",
        "age": 30,
        "password": "foo"
    },
    {
        "name": "Ben",
        "age": 20
    }
]
""".data(using: .utf8)!

struct User: Decodable {
    var name: String
    var age: Int
    var password: String?
}

let users = try JSONDecoder().decode([User].self, from: json)

for user in users {
    print(user)
}
//result
// User(name: "Bob", age: 30, password: Optional("foo"))
// User(name: "Ben", age: 20, password: nil)

Rename the key

The name of the json key and the name of the swift object key may be different. For example, when the json key is user_id and the swift object key is userId. Since decoding cannot be performed as it is, use Decodable's CodingKeys enum to enable decoding.


import Foundation

let json = """
[
    {
        "name": "Bob",
        "age": 30,
        "password": "foo",
        "user_id": 1
    },
    {
        "name": "Ben",
        "age": 20,
        "user_id": 2
    }
]
""".data(using: .utf8)!

struct User: Decodable {
    var name: String
    var age: Int
    var password: String?
    var userId: Int
    
    private enum CodingKeys: String, CodingKey {
        case name
        case age
        case password
        case userId = "user_id"
    }
}

let users = try JSONDecoder().decode([User].self, from: json)

for user in users {
    print(user)
}

You have successfully mapped the user_id to the userId.

Extract data from nested json

Decodable can be nested.


struct User: Decodable {
    let name: String
    let children: [Child]
    
    struct Child: Decodable {
        let name: String
        let teachers: [Teacher]
        
        struct Teacher: Decodable {
            let name: String
        }
    }
}

Therefore, it is possible to easily represent a nested JSON data structure.

import Foundation
let json = """
[
    {
        "name": "A",
        "children": [
            {
                "name": "B",
                "teachers": [
                    {
                        "name": "C"
                    }
                ]
            }
        ]
    },
    {
        "name": "E",
        "children": [
            {
                "name": "F",
                "teachers": [
                    {
                        "name": "G"
                    },
                    {
                        "name": "I"
                    }
                ]
            }
        ]
    }
]
""".data(using: .utf8)!

let users = try JSONDecoder().decode([User].self, from: json)
// [
//   User(
//     name: "A",
//     children: [
//       Child(
//         name: "B",
//         teachers: [ Teacher(name: "C") ]
//       )
//     ]
//   ),
//   User(
//     name: "E",
//     children: [
//       Child(
//         name: "F",
//         teachers: [ Teacher(name: "G"), Teacher(name: "I") ]
//       )
//     ]
//   )
// ]

Recommended Posts

Understand how to use Swift's JSON Decoder in 3 minutes
Understand in 5 minutes !! How to use Docker
How to use Lombok in Spring
How to use InjectorHolder in OpenAM
How to use classes in Java?
How to use JSON data in WebSocket communication (Java, JavaScript)
Multilingual Locale in Java How to use Locale
How to use custom helpers in rails
How to use named volume in docker-compose.yml
How to use Docker in VSCode DevContainer
How to use MySQL in Rails tutorial
How to use environment variables in RubyOnRails
How to use credentials.yml.enc introduced in Rails 5.2
How to assemble JSON directly in Jackson
How to use ExpandableListView in Android Studio
How to use Swift's Codable Super personal memo
[Rails] How to use select boxes in Ransack
How to use "sign_in" in integration test (RSpec)
How to use JQuery in js.erb of Rails6
[Rails] How to use PostgreSQL in Vagrant environment
How to use rbenv
How to use letter_opener_web
How to use with_option
How to use java.util.logging
How to use map
How to use Twitter4J
How to use active_hash! !!
How to use MapStruct
How to use hidden_field_tag
How to use TreeSet
[How to use label]
How to use identity
How to use hashes
How to use JUnit 5
How to use Dozer.mapper
How to use Gradle
How to use org.immutables
How to use java.util.stream.Collector
How to use VisualVM
How to use Map
[Ruby] How to use standard output in conditional branching
How to implement guest login in 5 minutes in rails portfolio
How to use Z3 library in Scala with Eclipse
Understand the characteristics of Scala in 5 minutes (Introduction to Scala)
How to use CommandLineRunner in Spring Batch of Spring Boot
How to use JDD library in Scala with Eclipse
How to use In-Memory Job repository in Spring Batch
Notes on how to use regular expressions in Java
[Java] How to use Map
How to use Chain API
[Java] How to use Map
How to use Priority Queuing
[Rails] How to use enum
How to use java Optional
How to use JUnit (beginner)
How to use Ruby return
[Rails] How to use enum
How to use @Builder (Lombok)
[Swift] How to use UserDefaults
How to use java class
How to use Swift UIScrollView