skip to Main Content

I run this error when I tried to parse a JSON response returned by an open API:

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

This happens in the following line of code:
let decodedWeatherData = try decoder.decode(WeatherData.self, from: data)
And here’s the part of decoding codes:

func parseWeatherJSON(data: Data) {
    let decoder = JSONDecoder()
    
    do {
        let decodedWeatherData = try decoder.decode(WeatherData.self, from: data)
        let id = decodedWeatherData.weather[0].id
        let temp = decodedWeatherData.main.temp
        let name = decodedWeatherData.name
        
        let weather = WeatherModel(conditionId: id, temperature: temp, cityName: name)
        print(weather.tempStr)
    } catch {
        print(error)
    }
}

Here’s my JSON response:

{
  "coord": {
    "lon": 121.4692,
    "lat": 31.2323
  },
  "weather": [
    {
      "id": 800,
      "main": "Clear",
      "description": "clear sky",
      "icon": "01n"
    }
  ],
  "base": "stations",
  "main": {
    "temp": 25.48,
    "feels_like": 26.36,
    "temp_min": 23.86,
    "temp_max": 26.95,
    "pressure": 1011,
    "humidity": 87
  },
  "visibility": 10000,
  "wind": {
    "speed": 3,
    "deg": 140
  },
  "clouds": {
    "all": 0
  },
  "dt": 1695067161,
  "sys": {
    "type": 2,
    "id": 2043475,
    "country": "CN",
    "sunrise": 1695073210,
    "sunset": 1695117382
  },
  "timezone": 28800,
  "id": 1796231,
  "name": "Shanghai Municipality",
  "cod": 200
}

My structure of WeatherData:

struct WeatherData: Codable {
    let name: String
    let main: Main
    let weather: [Weather]
}

struct Main: Codable {
    let temp: Double
}

struct Weather: Codable {
    let description: String
    let id: Int
}

It seems my structure correspond to the JSON response. I don’t know why the decoding was failed and CodingKeys can’t be associated

2

Answers


  1. The decoding is correct. The issue is in the data which you are getting from the network, there may be some other characters other than JSON, so it is throwing this type of error. I prepared data from the string just to demonstrate.

    let json = """
    {
      "coord": {
        "lon": 121.4692,
        "lat": 31.2323
      },
      "weather": [
        {
          "id": 800,
          "main": "Clear",
          "description": "clear sky",
          "icon": "01n"
        }
      ],
      "base": "stations",
      "main": {
        "temp": 25.48,
        "feels_like": 26.36,
        "temp_min": 23.86,
        "temp_max": 26.95,
        "pressure": 1011,
        "humidity": 87
      },
      "visibility": 10000,
      "wind": {
        "speed": 3,
        "deg": 140
      },
      "clouds": {
        "all": 0
      },
      "dt": 1695067161,
      "sys": {
        "type": 2,
        "id": 2043475,
        "country": "CN",
        "sunrise": 1695073210,
        "sunset": 1695117382
      },
      "timezone": 28800,
      "id": 1796231,
      "name": "Shanghai Municipality",
      "cod": 200
    }
    """
    let data = json.data(using: .utf8)
    
    Login or Signup to reply.
  2. The JSON listed is valid, but the error indicated that the JSON, at that time, provided by the Server was missing the key name, so the error arise.

    • This works well
    struct WeatherData: Codable {
        let name: String
        let main: Main
        let weather: [Weather]
    }
    
    struct Main: Codable {
        let temp: Double
    }
    
    struct Weather: Codable {
        let description: String
        let id: Int
    }
    
    func parseWeatherJSON(data: Data) {
        let decoder = JSONDecoder()
        
        do {
            let decodedWeatherData = try decoder.decode(WeatherData.self, from: data)
            print(decodedWeatherData)
        } catch {
            print(error)
        }
    }
    
    let jsonString = """
    {
      "coord": {
        "lon": 121.4692,
        "lat": 31.2323
      },
      "weather": [
        {
          "id": 800,
          "main": "Clear",
          "description": "clear sky",
          "icon": "01n"
        }
      ],
      "base": "stations",
      "main": {
        "temp": 25.48,
        "feels_like": 26.36,
        "temp_min": 23.86,
        "temp_max": 26.95,
        "pressure": 1011,
        "humidity": 87
      },
      "visibility": 10000,
      "wind": {
        "speed": 3,
        "deg": 140
      },
      "clouds": {
        "all": 0
      },
      "dt": 1695067161,
      "sys": {
        "type": 2,
        "id": 2043475,
        "country": "CN",
        "sunrise": 1695073210,
        "sunset": 1695117382
      },
      "timezone": 28800,
      "id": 1796231,
      "name": "Shanghai Municipality",
      "cod": 200
    }
    """
    
    
    if let data = jsonString.data(using: .utf8) {
        parseWeatherJSON(data: data)
    }
    
    
    • This dose not work

    Change one of JSON’s key name to nam, the error is the same, so that is the problem.

    let jsonString = """
    {
      ···
      "nam": "Shanghai Municipality",
      ···
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search