이 글은 이전글과 내용이 이어지는 글입니다.
이전 글 : iOS API JSON 데이터 가져오기 (날씨 API)
자. 이렇게 JSON 정보를 땡겨오기까지는 했다.
하지만, 이렇게 했다고 해서 내용이 읽혀지지도 않고, 요대로 앱으로 내보내기엔 도움도 안된다. 따라서 저기에서 정보들을 뽑아와야 한다.
그 전에, 저번 시간에 4단계로 구성했던 performRequest()
메서드에 task 부분을 후행 클로저로 수정하자. 클로저는 굳이 함수를 만들지 않고도 함수의 역할을 수행할 수 있는 기능이다.
더 알고 싶다면 Closures 를 확인해보자.
func performRequest(urlString: String) {
. . . [원래 코드와 동일하므로 생략]
// 후행 클로저로 선언한 completionHandler
let task = session.dataTask(with: url) { data, response, error in
if error != nil {
print(error!)
return
}
// 에러가 발생하지 않았다면 if let 구문으로 들어와 data(옵셔널 데이터)를 언래핑 하게 된다.
// data는 문자열로 쉽게 출력할 수 있다.
if let safeData = data {
// 언래핑 된 data를 전송한다.
// 클로저 내부에서 다른 클로저를 실행하는 경우 self를 추가해야 한다.
self.parseJSON(weatherData: safeData)
}
}
. . .
}
}
끝쪽에 위치하는 parseJSON()
또한 구현하자.
func parseJSON(weatherData: Data) {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode(WeatherData.self, from: weatherData)
print(decodedData.weather[0].description)
} catch {
print(error)
}
}
let decoder = JSONDecoder()
JSONDecoder() 메서드를 사용하면 JSON을 디코딩할 수 있다.
디코딩이란 Swift 형식으로 JSON 파일을 사용하는 방법이다.
do {
let decodedData = try decoder.decode(WeatherData.self, from: weatherData)
print(decodedData.weather[0].description)
} catch {
print(error)
}
type: 디코더 프로토콜을 준수하는 디코딩에 사용하는 유형
WeatherData 뿐만아니라 모든 유형을 지정하려면 self가 필요하다.
decode 자체가 throws를 사용하기 때문에 try 가 필요하다.
또한 에러를 막기 위해 do-catch구문도 사용하자.
그리고 상수로 받은 decodedData
에는 WeatherData
로 지정이 되었다.
따라서 WeatherData
안에 존재하는 변수, 상수, 함수등을 사용할 수 있다.
그러니까 디코딩을 위해서는 구조체를 사용해 JSON 파일처럼 구조를 짜줘야 한다는것이다.
따로 Swift 파일을 파서 만들기 바란다.
struct WeatherData: Decodable {
let name: String
let main: Main
let weather: [Weather]
}
// JSON에서 제공하는 이름 그대로 작성해줘야 한다.
struct Main: Decodable{
let temp: Double
}
struct Weather: Decodable {
let description: String
}
구조체 옆에 Decodable은 스스로 JSON 표현으로 디코딩할 수 있게 바꾸어주는 프로토콜이다.
JSON 파일의 객체 그대로 필요한 것들만 뽑아서 구조체를 구성했다.
그렇게 하고 앱 빌드를 하게 되면
(현재 print를 description 값으로 해놨다)
이렇게 JSON 내에서 보여지는 것들이 출력되게 된다.
이렇게 JSON 내에 정보들을 출력하는 것 까지 해보았다.
이후에 정보들은 알아서 Label에 추가해서 적용해보길 바란다.