Swift Tutorial · Advanced Swift · Lesson 27 of 30
Swift Codable and JSON
Encode and decode JSON with Codable, custom keys, snake_case conversion and dates.
Codable
Conform a type to Codable and the compiler generates the code to convert it to and from JSON (or property
lists). Nested Codable types and arrays work automatically.
import Foundation
struct Item: Codable {
let name: String
let price: Double
}
struct Order: Codable {
let id: Int
let items: [Item]
let note: String?
}
let order = Order(id: 42, items: [Item(name: "mug", price: 12.5)], note: nil)
let encoder = JSONEncoder()
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
let data = try encoder.encode(order)
print(String(decoding: data, as: UTF8.self))
let decoded = try JSONDecoder().decode(Order.self, from: data)
print(decoded.items[0].name, decoded.note ?? "no note")
Output
{
"id" : 42,
"items" : [
{
"name" : "mug",
"price" : 12.5
}
]
}
mug no noteRun this on your computer — see “Get Started” for setup.
Key strategies and custom keys
keyDecodingStrategy = .convertFromSnakeCase maps created_at to createdAt. CodingKeys renames
individual keys, and a missing optional key decodes as nil. Decoding errors say which key was wrong.
import Foundation
struct User: Decodable {
let id: Int
let fullName: String
let isAdmin: Bool
let nickname: String?
enum CodingKeys: String, CodingKey {
case id, fullName, nickname
case isAdmin = "admin"
}
}
let json = Data("""
[{"id": 1, "full_name": "Ana Silva", "admin": true},
{"id": 2, "full_name": "Ben Ode", "admin": false, "nickname": "benny"}]
""".utf8)
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let users = try decoder.decode([User].self, from: json)
for u in users { print(u.id, u.fullName, u.isAdmin, u.nickname ?? "-") }
do {
_ = try decoder.decode(User.self, from: Data(#"{"id": "one", "full_name": "X", "admin": false}"#.utf8))
} catch DecodingError.typeMismatch(_, let context) {
print("bad value for:", context.codingPath.map(\.stringValue))
}
Output
1 Ana Silva true - 2 Ben Ode false benny bad value for: ["id"]
Run this on your computer — see “Get Started” for setup.
Test yourself
What does keyDecodingStrategy = .convertFromSnakeCase do?
Lowercases all valuesMaps JSON keys like created_at to Swift properties like createdAtSorts the keysIgnores unknown keys
Show answer
Answer: Maps JSON keys like created_at to Swift properties like createdAt