Trouble extracting nested array data in Swift using RapidAPI

I’m having issues with a COVID-19 API from RapidAPI. The data looks like this:

{
  "country": "Canada",
  "provinces": [
    {
      "province": "Alberta",
      "confirmed": 754,
      "recovered": 0,
      "deaths": 9,
      "active": 0
    }
  ],
  "latitude": 56.130366,
  "longitude": -106.346771,
  "date": "2020-04-01"
}

I made these models:

struct Country: Codable {
  let country: String
  let provinces: [Province]
}

struct Province: Codable {
  let province: String
  let confirmed: Int
  let recovered: Int
  let deaths: Int
  let active: Int
}

But it won’t parse. It only works if I remove the provinces array from Country. What’s wrong? Here’s my code:

override func viewDidLoad() {
  super.viewDidLoad()
  
  ApiClient.fetchData(url: "myurl", apiKey: "mykey") { result in
    switch result {
    case .success(let data):
      if let countries = try? JSONDecoder().decode([Country].self, from: data) {
        let firstProvince = countries[0].provinces[0].province
        print(firstProvince)
      }
    case .failure(let error):
      print(error)
    }
  }
}

Any ideas why it’s not working? Thanks!

hey mate, looks like ur json is for a single country, not an array. try changing ur decode line to:

if let country = try? JSONDecoder().decode(Country.self, from: data) {
let firstProvince = country.provinces[0].province
print(firstProvince)
}

that should fix it. good luck!

I’ve encountered similar issues when working with nested JSON structures. The problem likely stems from the mismatch between your JSON data and the model you’ve created. The API response appears to be a single country object, not an array of countries.

Try modifying your decoding approach like this:

if let country = try? JSONDecoder().decode(Country.self, from: data) {
    if let firstProvince = country.provinces.first?.province {
        print(firstProvince)
    }
}

This should correctly parse the single Country object with its nested provinces array. If you’re expecting multiple countries, you might need to adjust your API call or wrap the response in an array structure.

Also, ensure your ApiClient is properly handling the response data. Sometimes API wrappers add extra layers to the JSON structure that need to be accounted for in your decoding process.

I’ve run into this exact problem before with nested JSON structures. The issue isn’t with your models, but with how you’re decoding the data. The JSON you’re receiving is for a single country, not an array of countries.

Try adjusting your decoding logic like this:

if let country = try? JSONDecoder().decode(Country.self, from: data) {
    if let firstProvince = country.provinces.first {
        print(firstProvince.province)
    }
}

This should work because you’re decoding a single Country object, not an array. If you’re expecting multiple countries from the API, you might need to wrap the response in an array or adjust your API call.

Also, double-check your API documentation. Sometimes, the actual data is nested under a key in the response, so you might need to drill down into the JSON before decoding. Hope this helps!