URLSession Life Cycle에 맞춰 https://home.openweathermap.org 에서 제공하는 데이터를 받아 앱에 보여주는 코드를 작성해보겠습니다
URLSession과 HTTP에 관한 기본 설명은 [iOS] - URLSession, HTTP 여기서 볼 수 있습니다.
let session = URLSession(configuration: .default)
guard let url = URL(String: "API주소") else { return }
제가 호출하고자하는 API는 다음과 같이 구성되어 있기 때문에
guard let url = URL(String: "https://api.openweathermap.org/data/2.5/weather?q=\(cityName)&appid=개인APIKey") else { return }
위와 같이 작성해 주었습니다
위 API를 호출하는 경우 다음과 같은 JSON파일을 받게 되는데
이 파일 중 weather, main, name 데이터만 필요하기 때문에 위 세 타입을 받는 객체(weatherInformation)를 생성해야합니다.
struct WeatherInformation: Codable {
let weather: ?
let main: ?
let name: String
}
struct Weather: Codable {
let id: Int
let main : String
let description: String
let icodn: String
}
struct Temp: Codable {
let temp: Double
let feelsLike: Double
let minTemp: Double
let maxTemp: Double
// Json 파일에 있더라도 사용하지 않는다면 정의해주지 않아도 됩니다.
//let pressure: Int
//let humidity: Int
// 편의를 위해 구조체에서 json파일의 데이터 이름과 프로퍼티의 이름을 다르게 정의한 경우 다음과 같은 설정이 필요합니다.
enum CodingKeys: String, CodingKey {
case temp
case feelsLike = "feels_like"
case minTemp = "temp_min"
case maxTemp = "temp_max"
}
}
struct WeatherInformation: Codable {
let weather: [Weather]
let temp: Temp
let name: String
enum CodingKeys: String, CodingKey {
case weather
case temp = "main"
case name
}
}
session.dataTask(with:url) { data, response, error in
}
API 호출에 성공하면 클로져의 data에 데이터가 들어가고, error는 Nil입니다.
session.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else { return }
}
따라서 다음과 같이 optional 타입(Data?)인 data를 binding 할 수 있습니다.
API호출에 성공하여 data에 데이터가 존재하는 경우,
미리 생성해놓은 WeatherInformation 타입으로 전달받은 데이터를 변환시켜야합니다.
JSON 데이터를 변환은 JSONdecoder객체를 사용하여 수행할 수 있습니다.
let decoder = JSONDecoder()
guard let weatherInformation = try? decoder.decode(WeatherInformation.self, from: data) else { return }
DispatchQueue.main.async {
self?.weatherStackView.isHidden = false
self?.configureView(weatherInformation: weatherInformation)
}
다음과 같이 URLSession을 사용하여 API를 호출하는 메서드가 완성되었습니다.