How to decode a nested JSON struct with Swift Decodable protocol?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Nested JSON is common in API responses, and Swift handles it well through the Decodable protocol. The key is to model your Swift types so they match the JSON shape exactly, then use custom coding keys when names differ. Once the structure is clear, decoding complex payloads becomes predictable and easy to test.
Start with a JSON Shape and Mirror It in Swift Types
When decoding fails, the most common reason is a mismatch between JSON nesting and Swift struct nesting. Always inspect the payload first and then define types that mirror each level.
Matching Decodable models:
Decode it with JSONDecoder:
This works because each nested object maps to a nested Swift type.
Flatten Nested Fields with Custom init(from:)
Sometimes you want a flat Swift model even when JSON is nested. In that case, implement custom decoding and traverse nested containers.
Use this pattern when you need a cleaner domain model for view logic or persistence.
Handle Optional Fields, Dates, and Arrays
Real API payloads are rarely perfect. Some fields may be missing, dates may use custom formats, and arrays can be empty.
Prefer decodeIfPresent behavior by declaring optional properties. That avoids hard failures when a field is legitimately absent.
If the backend date format is custom, use a formatter strategy:
This keeps date parsing explicit and stable across locales.
Add Diagnostics for Fast Debugging
When decoding fails, print the exact DecodingError so you can locate the failing key path quickly.
This is usually faster than guessing which field is wrong.
Common Pitfalls
A common mistake is defining a flat struct for nested JSON without custom decoding logic. Swift then cannot find keys at the expected level and throws key-not-found errors.
Another issue is forgetting CodingKeys when backend names use snake_case. Property names that differ from JSON keys must be mapped explicitly.
Developers also decode strict non-optional fields for data that is not guaranteed by the API. Use optionals for unstable fields and validate downstream where needed.
Summary
- Mirror JSON nesting in Swift types for reliable
Decodablebehavior. - Use custom coding keys whenever JSON field names differ.
- Implement
init(from:)when you need flattened app models. - Configure date decoding strategy to match backend date format.
- Use detailed
DecodingErrorhandling to debug failures quickly.

