Back to Guides
March 1, 20265 min read

Mastering JSON to Swift Codable for Dynamic APIs

Data serialization shouldn't be a bottleneck in iOS app development. Discover how the `Codable` protocol changed the game for Swift developers, and how to handle messy, dynamic JSON payloads.

The Pain of Manual JSON Serialization

Before Swift 4 introduced the `Codable` protocol, parsing JSON in iOS was notoriously cumbersome. Developers had to manually parse dictionaries (`[String: Any]`), cast values, and perform tedious optional binding. A simple typo in a string key would lead to runtime crashes.

Enter Swift Codable

`Codable` is actually a typealias for two protocols: `Encodable` and `Decodable`. By simply adopting this protocol, the Swift compiler automatically generates the required methods to encode to and decode from external representations like JSON.

Example JSON Payload

{
  "user_id": 98231,
  "first_name": "Sarah",
  "is_active": true,
  "last_login_date": "2026-03-01T15:00:00Z"
}

Handling Snake Case vs Camel Case

Most backend APIs return JSON keys in `snake_case` (e.g., `user_id`), but Swift conventions strongly dictate `camelCase` (e.g., `userId`) for properties. You handle this in one of two ways:

1. The CodingKeys Enum approach

You can explicitly map your Swift properties to the JSON keys using an embedded `CodingKeys` enum. This is perfect if the API keys are completely different from your variable names.

struct User: Codable {
    let id: Int
    let firstName: String
    let isActive: Bool
    
    enum CodingKeys: String, CodingKey {
        case id = "user_id"
        case firstName = "first_name"
        case isActive = "is_active"
    }
}

2. The Decoder keyDecodingStrategy approach

If the API strictly follows snake_case and your models strictly follow camelCase, you can skip the `CodingKeys` boilerplate entirely. Just tell the `JSONDecoder` how to behave:

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase

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

Dealing with Missing or Null Values

Production APIs are rarely perfect. A field might return `null`, or be missing from the JSON payload entirely. If your Swift property is a non-optional type (e.g., `let name: String`), and the JSON field is missing, the entire decoding process will throw an error and fail.

Rule of thumb:

If there is any chance an API field might be missing or null, ALWAYS mark the Swift property as Optional (e.g., `let profileImageUrl: String?`).

Automating the Boilerplate

While `Codable` is powerful, writing the structs out by hand for massive JSON responses with deeply nested objects can take hours.

This is exactly why we built the JSON to Model Generator. You can paste any raw JSON directly into our generator, select Swift, and instantly receive fully-typed, nested Codable structs ready to be dropped into Xcode.