-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Optionals
-
Section 4: Object-Oriented and Value Types
-
Section 5: Memory Management
-
Section 6: Generics and Error Handling
-
Section 7: Concurrency
-
Section 8: Working with Collections
-
Section 9: Codable and Data Handling
-
Section 10: Protocol-Oriented Programming
-
Section 11: Testing and Tooling
-
Section 12: Practical Projects
-
Section 13: Interview Practice
-
Section 14: More Practice Exercises
-
Section 15: More Standard Library
-
Section 16: Advanced Concurrency
-
Section 17: Foundation Framework Deep Dive
-
Section 18: URLSession and Networking Deep Dive
-
Section 19: Combine Framework
-
Section 20: SwiftUI Fundamentals for Swift Developers
-
Section 21: Server-Side Swift with Vapor
-
Section 22: Swift Package Manager Deep Dive
-
Section 23: Swift Concurrency Deep Dive
-
Section 24: More Language Features
-
Section 25: Error Handling Deep Dive
-
Section 26: Testing Deep Dive
-
Section 27: Data Structures and Algorithms in Swift
-
Section 28: More Practice Exercises
-
Section 29: More Interview Practice
-
Section 30: Swift Macros (Swift 5.9+)
-
Section 31: Property Wrappers Ecosystem
-
Section 32: Swift Interop Deep Dive
-
Section 33: iOS App Architecture Patterns
-
Section 34: Performance and Debugging
-
Section 35: App Distribution and CI/CD
-
Section 36: More Practical Projects
-
Section 37: SwiftData and Persistence
-
Section 38: More Design Patterns
-
Section 39: More Review and Practice
-
Section 40: More Foundation Deep Dive
-
Section 41: Advanced Collections in Swift
-
Section 42: Advanced Generics Practice
-
Section 43: UIKit for Legacy and Hybrid Apps
-
Section 44: watchOS and visionOS Development Basics
-
Section 45: More Networking Patterns
-
Section 46: More Testing Practice
-
Section 47: Accessibility in Swift Apps
-
Section 48: Localization
-
Section 49: More Practical Projects Round 2
-
Section 50: Swift Charts Framework
-
Section 51: More Interview and Algorithm Practice
-
Section 52: Final Practice and Mastery
-
Section 53: Swift Compiler and Build System
-
Section 54: More Concurrency Practice
-
Section 55: App Store Guidelines and Review
-
Section 56: More Design and Architecture
59: Practice Exercise: Building a Simple Weather Data Model with Codable
When I first started working with Codable, I had this nagging belief that if the JSON coming from an API didn't perfectly match my Swift property names, I was in for a nightmare of manual mapping. I thought I'd have to write a custom init(from decoder:) method for every single struct, manually extracting values and assigning them one by one. It felt like I was back in the days of manual dictionary parsing, which is exactly what Codable is supposed to save us from.
The "I have to write a custom initializer" Panic
Let's look at why that mindset is a trap. Imagine you're hitting a weather API, and the JSON looks like this:
{
"temp_c": 22.5,
"wind_kph": 15.0,
"condition_text": "Partly Cloudy"
}
In Swift, we want our properties to follow camelCase conventions. If you try to define your struct like this, it will fail to decode because temp_c doesn't match temperatureCelsius:
struct Weather: Codable {
let temperatureCelsius: Double
let windKph: Double
let conditionText: String
}
The mistake is thinking that the only way to fix this is to write a custom initializer that manually maps "temp_c" to temperatureCelsius. While you can do that, it's a massive waste of time and makes your code brittle. You don't need to rewrite the decoding logic; you just need to tell Swift how the keys map.
Letting CodingKeys do the Heavy Lifting
The actual solution is a special enum called CodingKeys. As long as you name the enum exactly CodingKeys and make it conform to String, CodingKey, Swift will use it instead of the property names to match the JSON.
Here is how I would actually set up that weather model. Notice how I keep the Swift properties clean and idiomatic while still mapping them to the API's underscored keys:
struct Weather: Codable {
let temperatureCelsius: Double
let windKph: Double
let conditionText: String
enum CodingKeys: String, CodingKey {
case temperatureCelsius = "temp_c"
case windKph = "wind_kph"
case conditionText = "condition_text"
}
}
By doing this, JSONDecoder handles all the logic. You get the best of both worlds: an API-compliant mapping and a codebase that actually follows Swift style guides. I've spent far too many hours in the past writing manual initializers before remembering that CodingKeys exists—don't make that same mistake.
Handling the "Missing Data" Reality
One last thing: in real-world weather data, APIs are flaky. Sometimes the wind_kph value is missing because the sensor is down, or the condition_text is null. If you define a property as non-optional and the key is missing from the JSON, JSONDecoder will throw an error and fail to decode the entire object.
I always recommend making "edge-case" fields optional. If the wind speed is missing, the app shouldn't crash or fail to load the temperature; it should just show "N/A" for the wind. Use Double? or String? for anything that isn't 100% guaranteed by the API provider.
📋 Practical Task
Exercise: Creating a Robust Weather Forecast Parser
You have been provided with a JSON string representing a 3-day weather forecast. Your task is to build the Swift data models necessary to decode this JSON into strongly typed objects.
The JSON Data:
let jsonString = """
{
"city_name": "Seattle",
"forecast": [
{ "day": "Monday", "high_temp": 18.5, "low_temp": 12.0, "precip_chance": 0.8 },
{ "day": "Tuesday", "high_temp": 20.1, "low_temp": 14.2, "precip_chance": 0.1 },
{ "day": "Wednesday", "high_temp": 17.0, "low_temp": 11.5 }
]
}
"""
Requirements:
- Create a
WeatherForecaststruct and aDailyForecaststruct. - Use
CodingKeysto map the snake_case JSON keys (e.g.,city_name,high_temp) to camelCase Swift properties (e.g.,cityName,highTemp). - Ensure that
precipChanceis an optionalDouble, as it is missing from the Wednesday entry. - Write the code to convert the
jsonStringinto aWeatherForecastinstance usingJSONDecoder. - Print the
cityNameand thehighTempof the first day in the forecast to the console.
There are no comments for now.