JSONDecoder unable to decode my API

I'm trying to get JSONDecoder to decode data from an API. I know the content of the data is valid JSON has I've downloaded it independently and verified it.

let decoder = JSONDecoder()
let dataStr = String(bytes: data, encoding: String.Encoding.utf8)
print(dataStr)
do {
     let combinedForecast = try decoder.decode(NWCombinedForecast.self, from: data)
     print("getting data")
     completion?(combinedForecast)
} catch {
     let msg = error.localizedDescription
     print(msg)
}

I can use the inspector to see that dataStr is set and valid. I can also see data is defined as Foundation.Data, but the try line always throws and error and before 'getting data' is printed, it drops down to the catch block. Below is the inspector showing that dataStr is set, hopefully showing that data is there, but decoder is not doing anything useful with it.

Incase it helps, this is the NWCombinedForecast struct that I am trying to decode the data into

public struct NWCombinedForecast: Codable {
    let forecast: [NWForecast]
    let summary: [NWSummary]
    let location: NWLocation
}
Answered by ITSD in 725225022

Ah progress, Maybe the auto generation of the Swift model is at fault. There are optional parts of the JSON which it didn't pick up (sample must of contained them all) and when I used print(error) instead of print(error.localizedDescription) I got a more helpful output

keyNotFound(CodingKeys(stringValue: "precipitation_amount", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "forecast", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: "precipitation_amount", intValue: nil) ("precipitation_amount").", underlyingError: nil))

It would help to show the complete dataStr

It seems you have no data.

For testing, try:

let dataStr = String(bytes: data, encoding: String.Encoding.utf8)
print(dataStr)
let data2 = dataStr.data(using: .utf8, allowLossyConversion: false) ?? "---"
do {
     let combinedForecast = try decoder.decode(NWCombinedForecast.self, from: data2)  // Change here
     print("getting data")

And tell what you get

Xcode has the full value, this is just truncated by the inspector.

"{"forecast":[{"air_temperature":8.532769775400027,"cloud_coverage":0.9872359037,"relative_humidity":90.86474776,"wind_speed":5.56043127408,"wind_direction":131.1224219363,"wind_speed_description":"Light wind","wind_gust":16.74143199936,"wind_gust_description":"Moderate","coverage_label":"cloudy","datetime":"2022-08-26T00:00:00+12:00","label":"12:00am","duration":1.0,"phase":"night","icon":"cloudy"},{"air_temperature":8.456719970700021,"cloud_coverage":0.9532022476,"precipitation_amount":0.0,"snow_amount":0.0,"relative_humidity":90.19520283,"wind_speed":5.46783980976,"wind_direction":122.6922215381,"wind_speed_description":"Light wind","wind_gust":18.46313724528,"wind_gust_description":"Moderate","coverage_label":"cloudy","precipitation_label":"none","datetime":"2022-08-26T01:00:00+12:00","label":"1:00am","duration":1.0,"phase":"night","icon":"cloudy"},{"air_temperature":8.32317504880001,"cloud_coverage":0.9182502031,"precipitation_amount":0.0,"snow_amount":0.0,"relative_humidity":89.92497325,"wind_speed":5.43"...

I know what the API returns and it is valid, and I built the Swift models using a sample JSON and the QuickType.io site so I am pretty sure parsing them should not be an issue.

Using your debug code both data and data2 appear to have the same value of "(Foundation.Data?) 66469 Bytes" and the "try decoder.decode" line still crashes with the same error "The data couldn’t be read because it is missing."

Accepted Answer

Ah progress, Maybe the auto generation of the Swift model is at fault. There are optional parts of the JSON which it didn't pick up (sample must of contained them all) and when I used print(error) instead of print(error.localizedDescription) I got a more helpful output

keyNotFound(CodingKeys(stringValue: "precipitation_amount", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "forecast", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: "precipitation_amount", intValue: nil) ("precipitation_amount").", underlyingError: nil))

JSONDecoder unable to decode my API
 
 
Q