보통 서버에서 json data를 받아와 사용할 일이 있으면 해당 data에 해당하는 객체를 다 만들어서 JsonDecoder
를 사용해 받은 정보를 모두 변환하는 방법을 사용할 것이다
그런데 프로젝트 진행 중 오픈 API인 Open Weather Map 에서 필요한 정보 단 두 개만 받아와 진행해야할 상황이 생겼다
받아온 data 이렇게 많으나 이중 weather
의 main
과 icon
만 받아와야 하는 것이다
물론 서버팀과 얘기를 해서 필요한 정보로만 가공을 해달라고 할 수 있겠지만 이렇게 내가 해당 data 변경을 요청할 수 없을 때는 JSONSerialization을 통해 원하는 정보만 가져올 수 있다
일단 먼저 최종 코드를 보자면 위와 같은 코드를 통해 원하는 정보를 가져올 수 있다
그 과정을 하나 하나 살펴보려고 한다
맨 처음 소개했던 data를 보면
"coord"
같은 경우 key: {string: double, string: double}
의 형태이고
"weather"
의 경우 key : [배열]
이런 형태이므로
key : Any
즉, String : Any
로 퉁(?)쳐서 data를 받아와야 하며 그 부분이 밑줄 친 부분이다
(솔직히 options: [] << 이건 뭐 하는 애인지 잘 모르겠음...)
그래서 위 json을 print해보면
이렇게 맨 위에서 postman으로 확인 했던 data들이 잘 나오는 것을 볼 수있다
(중간에 name을 잘 못받아오긴 하는거 같은데 이건 일단 지금은 필요없는 것이니까...)
그래서 위 데이터중 우리가 필요한 icon
과 main
을 가져오기 위해서는 조금 더 추가 작업이 필요한 것이다
icon
과 main
을 가져오기 위해서는 1번에서 만들어준 [String: Any]타입의 json에서 weather
를 먼저 가져올 필요가 있다
postman을 다시 확인해보면
weather
의 경우 "weather": [배열] 타입으로 되어있으며 그 배열 내부를 보면 id
는 Int값을 나머지들은 String값을 갖고 있어 마찬가지로 [String: Any]로 퉁(?) 쳐서 가져와야 한다
밑줄 부분 처럼 가져와야하는데 이 형태가 잘 이해가 되지 않을 수 있어서 조금 더 설명해보자면
json
에 "weather"
라는 키의 값을 가져오려고 합니다~ -> 여기서의 값은 [값의 타입]
< 이형태의 값을 의미함
그래서 값의 타입이 뭔지 확인을 해보니 배열 형태인데 그 배열 속을 또 보니 String: Any
타입입니다~ -> [String: Any]
<< String: Any
타입을 가진 배열
=> 1번 [값의 타입]
에서 값의 타입에 2번을 그대로 대입하면 [[String: Any]]
즉 위에서 밑 줄 친 부분의 타입이 나오는 것이다
그래서 가져온 weather
를 print 해보면
"weather"
의 요소들을 잘 가져온다
2번에서 가져온 weather의 경우 요소가 한개 밖에 없지만 어쨌든 배열이므로 for 구문을 통해 접근을 해준 뒤 그 안에서 "main"
의 값과 "icon"
의 값을 가져온다
(만약 "main"
과 "icon"
이 아닌 "id"
의 값을 가져오고 싶다면 as? Int 로 캐스팅을 하면 될것이다)
가져온 값들을 각각 print해보면
원하는 값을 정상적으로 가져오는 것을 볼 수 있다