Skip to content
AgileLogics
6 min read

Codable and JSON

Prerequisites: Structs, Error handling

JSON is the most common format for sending data between programs — every web API speaks it. Swift converts between JSON and your own types with the Codable protocol, and the compiler writes the conversion code for you.

Encoding: Swift → JSON

import Foundation

struct User: Codable {
    let name: String
    let age: Int
    let tags: [String]
}

let user = User(name: "Ada", age: 36, tags: ["admin", "beta"])

let encoder = JSONEncoder()
encoder.outputFormatting = [.sortedKeys]
let data = try encoder.encode(user)
print(String(decoding: data, as: UTF8.self))
{"age":36,"name":"Ada","tags":["admin","beta"]}

.sortedKeys makes the key order predictable; add .prettyPrinted for indented, human-readable output.

Decoding: JSON → Swift

import Foundation

struct User: Codable {
    let name: String
    let age: Int
    let email: String?
}

let json = """
{"name": "Ada", "age": 36}
"""

do {
    let user = try JSONDecoder().decode(User.self, from: Data(json.utf8))
    print(user.name, user.age, user.email ?? "no email")
} catch {
    print("Invalid JSON: \(error)")
}
Ada 36 no email
  • Decoding can fail (bad JSON, missing or wrongly-typed fields), so it throws.
  • An optional property may be missing from the JSON; a non-optional one must be present.
  • Arrays decode with [User].self.

Different key names

APIs often use snake_case keys. Either let the decoder convert them:

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase  // "created_at" → createdAt

or map names explicitly with a CodingKeys enum:

struct Product: Codable {
    let id: Int
    let displayName: String

    enum CodingKeys: String, CodingKey {
        case id
        case displayName = "title"
    }
}

Paste a sample API response into the JSON Formatter to see its structure before writing the matching structs.

Common mistakes

  • Making a property non-optional when the API sometimes leaves it out — the whole decode fails with a keyNotFound error.
  • Ignoring the decoding error. Print it: it names the exact key and problem.