Activity 1
Decode a nested profile
Create Codable Profile and Address models, then decode JSON containing a nested address and an optional biography.
Hint: Make a property optional only when the payload contract permits absence or null.
Swift Fundamentals
Convert Swift models to and from JSON safely with Codable, coding keys, nested containers, and decoding strategies.
Before you begin
Learning stage
Codable combines Encodable and Decodable. When a model's stored properties also conform, Swift can usually synthesize the code required to convert between that model and an external representation such as JSON. JSONDecoder creates Swift values from Data, while JSONEncoder produces Data from Swift values.
Your model should describe the contract you actually expect. Use CodingKeys when external names differ from Swift naming, optionals only when a field may legitimately be absent or null, and custom decoding when the payload cannot be represented safely by synthesis. Decoding can throw, so inspect and preserve useful errors instead of silently replacing invalid data.
Learning stage
The model maps snake-case JSON to Swift-style property names and decodes the timestamp with an explicit strategy.
import Foundation
struct Course: Codable {
let id: Int
let title: String
let publishedAt: Date
let instructor: Instructor?
enum CodingKeys: String, CodingKey {
case id, title, instructor
case publishedAt = "published_at"
}
}
struct Instructor: Codable {
let name: String
}
let json = #"{"id":7,"title":"Swift Fundamentals","published_at":"2026-10-25T09:30:00Z","instructor":{"name":"Mina"}}"#
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
do {
let course = try decoder.decode(Course.self, from: Data(json.utf8))
print(course.title)
} catch {
print("Unable to decode course: (error)")
}Learning stage
These concepts appear throughout production iOS code. Focus on the requirement each technique communicates.
Learning stage
Notice these mistakes early so the compiler and type system can help instead of becoming obstacles.
Learning stage
Work through these activities in a small Xcode project. No embedded playground is required on this site.
Activity 1
Create Codable Profile and Address models, then decode JSON containing a nested address and an optional biography.
Hint: Make a property optional only when the payload contract permits absence or null.
Activity 2
Decode first_name, last_name, and created_at into Swift-style property names. Configure a suitable date strategy.
Hint: Use CodingKeys for names and configure the JSONDecoder before decoding.
Learning stage
Answer each question before revealing the explanation.
QUESTION 1
Encodable and Decodable together
Codable is a type alias combining both conversion directions; it is not limited to JSON.
QUESTION 2
Decoding throws an error, commonly a keyNotFound DecodingError.
A missing required field violates the model's declared decoding contract.
Learning stage
Explain the idea in terms of its purpose, behavior, and tradeoffs rather than reciting syntax.
Short answer: No. Optionality should match the service contract and the domain meaning of absence.
Making everything optional hides contract regressions and spreads uncertainty throughout the app. Required fields should fail decoding when missing. Optional fields are appropriate when null or absence is a valid response. At an API boundary, transport models can be validated and mapped into stronger domain models.
Possible follow-ups
Learning stage
Codable connects external data with Swift's type system. Model the real contract, configure representation strategies explicitly, and treat decoding failures as useful evidence rather than something to hide.