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.
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
}
let json = """
{
"name": "Bob",
"age": 20,
}
"""
let jsonData = json.data(using: .utf8)!
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
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)
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.
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