title: JSON parsing in Swift 4 with complex & nested data
body: <p>I am currently trying to make a weather app using JSON from <a href="https://openweathermap.org" rel="nofollow noreferrer">https://openweathermap.org</a> but I am having trouble with the weather part in the JSON file. I am not sure how to access the 'id' value inside the object.</p>
  
  <pre><code>{
    "base": "stations",
    "clouds": {
      "all": 36
    },
    "cod": 200,
    "coord": {
      "lat": 51.51,
      "lon":
        -0.13
    },
    "dt": 1507497600,
    "id": 2643743,
    "main": {
      "humidity": 82,
      "pressure": 1021,
      "temp": 10.65,
      "temp_max": 13,
      "temp_min": 9
    },
    "name": "London",
    "sys": {
      "country": "GB",
      "id": 5091,
      "message": 0.0036,
      "sunrise": 1507443264,
      "sunset": 1507483213,
      "type": 1
    },
    "visibility": 10000,
    "weather": [{
      "description": "scattered clouds",
      "icon": "03n",
      "id": 802,
      "main": "Clouds"
    }],
    "wind": {
      "deg": 200,
      "speed": 1.5
    }
  }
  </code></pre>
  
  <p>How would I be able to get the data in there. In my swift code, I am using structures that conform to the new 'codable' protocol in swift 4.</p>
  
  <pre><code>// all structures for the data
  struct CurrentLocalWeather: Codable {
      let base: String
      let clouds: clouds
      let cod: Int
      let coord: coord
      let dt: Int
      let id: Int
      let main: main
      let name: String
      let sys: sys
      let visibility: Int
      let weather: [weather]
      let wind: wind
      }  
  
  struct clouds: Codable {
      let all: Int
  }
  
  struct coord: Codable {
      let lat: Double
      let lon: Double
  }
  
  struct main: Codable {
      let humidity: Double
      let pressure: Double
      let temp: Double
      let temp_max: Double
      let temp_min: Double
  }
  
  struct sys: Codable {
      let country: String
      let id: Int
      let message: Double
      let sunrise: Double
      let sunset: Double
      let type: Int
  }
  
  struct weather: Codable {
      let description: String
      let icon: String
      let id: Int
      let main: String
  }
  
  struct wind: Codable {
      let deg: Double
      let speed: Double
  }
  
  // Get data from weather server
  func getCurrentWeatherData() {
  
          let jsonUrlString = "https://api.openweathermap.org/data/2.5/weather?id=2643743&amp;units=metric&amp;APPID=fdf04e9483817ae2fa77048f7e6705e8"
  
          guard let url = URL(string: jsonUrlString) else { return }
  
          URLSession.shared.dataTask(with: url) { (data, response, err) in
  
              guard let data = data else { return }
  
              do {
                  let decoder = JSONDecoder()
                  decoder.dateDecodingStrategy = .iso8601
  
                  let json = try decoder.decode(CurrentLocalWeather.self, from: data)
  
                  print("Data Successfully Retrieved!\nServer Response: \(json.cod)\nLocation: \(json.name)")
  
                  DispatchQueue.main.async() {
                      // Any of the following allows me to access the data from the JSON 
                      self.locationLabel.text = "\(json.name)"
                      self.temperatureLabel.text = "Currently: \(json.main.temp)ºC"
                      self.highTemperatureLabel.text = "High: \(json.main.temp_max)ºC"
                      self.lowTemperatureLabel.text = "Low: \(json.main.temp_min)ºC"
                      self.sunriseLabel.text = "\(self.convertFromUnixToNormal(time: json.sys.sunrise))"
                      self.sunsetLabel.text = "\(self.convertFromUnixToNormal(time: json.sys.sunset))"
                      self.humidityLabel.text = "Humidity: \(json.main.humidity)%"
                      self.pressureLabel.text = "Pressure: \(json.main.pressure) hPa"
                      self.windSpeedLabel.text = "Wind Speed: \(json.wind.speed) km/h"
  
  
                  }
              } catch let jsonErr {
                  print("Error: \(jsonErr)")
              }
  
          }.resume()
      }
  </code></pre>