Swift JSON decoding fails with nested array structures from API response

I’m working with a COVID-19 data API and having trouble decoding nested arrays in Swift. The API returns data that looks like this:

[
  {
    "country": "USA",
    "states": [
      {
        "state": "California",
        "cases": 1250,
        "deaths": 15,
        "recovered": 200,
        "active": 1035
      }
    ],
    "lat": 37.0902,
    "lng": -95.7129,
    "updated": "2020-04-01"
  }
]

I created these data models:

struct CountryData: Codable {
    let country: String
    let states: [StateInfo]
}

struct StateInfo: Codable {
    let state: String
    let cases: Int
    let deaths: Int
    let recovered: Int
    let active: Int
}

The weird thing is that JSON parsing only works when I remove the nested array:

struct CountryData: Codable {
    let country: String
    // let states: [StateInfo]  // commenting this out makes it work
}

Here’s my parsing code:

override func viewDidLoad() {
    super.viewDidLoad()
    
    APIManager.shared.fetchData(url: "api-endpoint", apiKey: "abc123") { responseData in
        guard let responseData = responseData else { return }
        
        do {
            let countries = try JSONDecoder().decode([CountryData].self, from: responseData)
            let firstState = countries[0].states[0].state
            self.stateName = firstState
            
            DispatchQueue.main.async {
                print(self.stateName)
            }
        } catch {
            print("Decoding failed: \(error)")
        }
    }
}

What could be wrong with my model structure? The parsing fails whenever I include the nested array property.

I’ve hit this exact problem before. It’s usually inconsistent data types in the nested array - the API returns string values instead of integers for fields like cases, deaths, or recovered in some responses. Even if most records have proper integers, this breaks the entire decoding process. Try making your StateInfo model more flexible by using String for numeric fields and converting them manually, or implement custom decoding with CodingKeys. Another common issue is missing properties - the decoder expects all fields unless they’re optionals. I’d add optional properties to StateInfo first, then gradually make them required once you confirm the data’s consistent. Since removing the nested array works, your outer structure is fine.

this looks like a case sensitivity problem. json decoders need exact property name matches. check if your api sends “States” (capital S) or “state_info” (with underscores) instead of camelCase. some apis also return empty arrays instead of null - that should work fine, but double-check your actual response data.

Your API response probably doesn’t match your model exactly. Even though your sample JSON looks right, here’s what usually goes wrong. First, check if the API sometimes sends null values for the states array or properties inside StateInfo. Swift’s Codable is picky about data types - if the API sends null for an Int field like cases or deaths, the whole thing fails. You might need optional properties like let cases: Int? or default values with CodingKeys. The API might also have extra fields you’re not handling, though that usually doesn’t break anything. I’d print the raw response as a string first to see exactly what you’re getting, then compare it field by field with your models. Also try decoding just one CountryData object instead of an array - that’ll tell you if the problem is with StateInfo or the outer structure.