Skip to Content
Course content

59: Practice Exercise: Building a Simple Weather Data Model with Codable

Click on the "Edit" button in the top corner of the screen to edit your slide content.

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 WeatherForecast struct and a DailyForecast struct.
  • Use CodingKeys to map the snake_case JSON keys (e.g., city_name, high_temp) to camelCase Swift properties (e.g., cityName, highTemp).
  • Ensure that precipChance is an optional Double, as it is missing from the Wednesday entry.
  • Write the code to convert the jsonString into a WeatherForecast instance using JSONDecoder.
  • Print the cityName and the highTemp of the first day in the forecast to the console.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.