Codable

코더블 프로토콜을 체택하면 디코더블과 인코더블 모두 체택한 것임.

코더블을 사용해 JSON데이터를 객체로 받아보자

-날씨정보 JSON

{
"coord": {
"lon": 126.9778,
"lat": 37.5683
},
"weather": [
{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10d"
}
],
"base": "stations",
"main": {
"temp": 287.9,
"feels_like": 286.58,
"temp_min": 284.84,
"temp_max": 287.93,
"pressure": 1017,
"humidity": 44
},
"visibility": 10000,
"wind": {
"speed": 3.6,
"deg": 150
},
"rain": {
"1h": 0.11
},
"clouds": {
"all": 0
},
"dt": 1647506291,
"sys": {
"type": 1,
"id": 8105,
"country": "KR",
"sunrise": 1647466864,
"sunset": 1647510011
},
"timezone": 32400,
"id": 1835848,
"name": "Seoul",
"cod": 200
}
  1. 날씨정보를 받아올 객체
import Foundation

struct WeatherInformation: Codable {
  let weather: [Weather]
  let temp: Temp
  let name: String

  enum CodingKeys: String, CodingKey {
    case weather
    case temp = "main"
    case name
  }
}

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

struct Temp: Codable {
  let temp: Double
  let feelsLike: Double
  let minTemp: Double
  let maxTemp: Double
	//키값과 변수명을 다르게 설정하고 싶은 경우
  enum CodingKeys: String, CodingKey {
    case temp
    case feelsLike = "feels_like"
    case minTemp = "temp_min"
    case maxTemp = "temp_max"
  }
}

HTTP 통신후 얻은 JSON정보를 객체에 넣어보자

func getCurrentWeather(cityName: String) {
    guard let url = URL(string: "<https://api.openweathermap.org/data/2.5/weather?q=\\>
(cityName)&appid=bd4f07b96b68f8e5a84c55e4effdded8") else { return }
    let session = URLSession(configuration: .default)
    session.dataTask(with: url) { [weak self] data, response, error in
      let successRange = (200..<300)
      guard let data = data, error == nil else { return }
      let decoder = JSONDecoder()
      if let response = response as? HTTPURLResponse, successRange.contains(response.statusCode) {
        guard let weatherInformation = try? decoder.decode(WeatherInformation.self, from: data) else { return }
        DispatchQueue.main.async {
          self?.weatherStackView.isHidden = false
          self?.configureView(weatherInformation: weatherInformation)
        }
      } else {
        guard let errorMesaage = try? decoder.decode(ErrorMessage.self, from: data) else { return }
        DispatchQueue.main.async {
          self?.showAlert(message: errorMesaage.message)
        }
      }

    }.resume()
  }