저는 Parsing하는 과정을 좋아합니다. 예쁘게 잘 짜여진 API에서 원하는 자료를 꺼내오는 게 마치 보물을 찾아오는 것 같아요 ㅎㅎ
보통 JSON이 많이 사용이 되고 있기 때문에 JSON 형태일 때 어떻게 자료를 parsing 하는지 예시를 통해서 알아보겠습니다.
1) Array형태( [ ] )인 경우
위의 JSON은 상당히 단순한 형태입니다. 보시면 아시겠지만 userId, id, title, body 모두 같은 레벨에 있어서 여러 뎁스를 거치지 않아도 원하는 값을 가져올 수 있게 되어있습니다. 그리고 {userId, id, title, body}가 array 안에 들어가 있는 구조입니다.
이 경우에는 data의 structure를 아래와 같이 잡아주면 끝입니다. 더 타고 들어갈 필요가 없기 때문에 한 번에 끝납니다.
1
2
3
4
5
6
|
struct Data: Codable {
let userId: Int
let id: Int
let title: String
let body: String
}
|
cs |
이렇게 Data structure를 만들어주고 parsing을 할 때는 아래처럼 [ ] 안에 Data가 담긴 형태로 parse하면 됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
guard let data = data else {
return
}
do {
//Data가 array안에 담겨있기 때문에 decode 시에 array 형태로 해주어야 합니다.
let decodedData = try JSONDecoder().decode([Data].self, from: data)
print(decodedData[0].title)
//[Data] array 0번째 요소의 title이 프린트 됩니다. } catch let jsonErr {
print("Error serializing:", jsonErr)
}
|
cs |
2) { } 로 감싸져 있는 경우
이번에는 여러 뎁스를 들어가는 조금은 복잡한 JSON을 parsing 해보는 방법을 알아보겠습니다.
아래의 JSON의 경우 가장 큰 데이터 덩어리가 { } 안에 담겨있고 response 부터 시작해 여러 레벨에 거쳐 정보들이 들어있음을 알 수 있습니다.
단순하게 나타내면 이렇게 볼 수 있겠습니다.
상당히 복잡해보이지만, 겁먹지 말고 내가 원하는 정보가 어디에 있는지부터 확인해보면 됩니다.
이 중에서 한번 ctpvNm을 가져오려면 어떻게 하면 될까요?
먼저 가장 큰 부분인 response부터 시작해서 response -> body -> Items -> Item -> ctpvNm 의 순서로 structure를 구성하여 정보를 빼내면 되겠다는 것을 확인해줍니다.
가장 먼저 response를 담는 structure인 Response를 만들어줍니다. 그리고 그 안의 요소인 response는 Body 타입으로 지정해주었습니다. (Body type은 임의로 붙인 이름으로 다른 이름을 사용해도 무관합니다. 다만 우리가 타고 들어갈 response ->body -> Items -> Item -> ctpvNm는 임의로 이름을 지어서는 안되고 반드시 JSON에 나온 명칭을 그대로 사용해주어야 합니다. )
1
2
3
|
struct Response: Codable {
let response: Body
}
|
cs |
이번에는 Body structure를 선언합니다.
1
2
3
|
struct Body: Codable {
let body: Items
}
|
cs |
다음으로는 Items structure를 선언합니다.
1
2
3
|
struct Items: Codable {
let items: Item
}
|
cs |
그 다음으로는 Item structure를 선언해주면 되겠죠?
item의 경우는 array 구조이기 때문에 데이터 타입도 array 형태로 설정해주어야만 합니다.
1
2
3
|
struct Item: Codable {
let item: [CityInfo]
}
|
cs |
마지막으로 CityInfo structure를 선언해주면 끝입니다!
1
2
3
|
struct CityInfo: Codable {
let ctpvNm: String
}
|
cs |
더 이상 타고 들어갈 자료가 없고 ctpvNm은 String형태이므로 String으로 타입을 명시해주면 됩니다.
설정해야 하는 것이 많지만 그래도 하는 방법만 알면 전혀 어렵지 않습니다.
그런 다음 parsing을 해줍니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
guard let data = data else {
return
}
do {
let decodedData = try JSONDecoder().decode(Response.self, from: data)
print(decodedData.response.body.items.item[0].ctpvNm)
//"인천"
} catch let jsonErr {
print("Error serializing:", jsonErr)
}
|
cs |
이번 JSON은 array안에 담겨 있지 않았기 때문에 decode하는 데이터 형태에 [Response]가 아닌 Response를 그대로 입력해주면 됩니다.
강의에서 알려준 JSON 형태와 다른 JSON을 맞닥트렸을 때 상당히 머리가 복잡했는데,
구글링 및 시행착오로 그 방법을 알고나니 JSON parsing이 오히려 재밌어졌습니다. 데이터를 유용하게 사용하는 것에도 관심이 많은 저는 API를 잘 활용하여 작은 프로젝트도 해볼까 생각 중입니다.
혹시 질문이 있으시거나 잘못된 부분, 개선점 등 알려주실 분들은 편하게 댓글 남겨주세요!
감사합니다 ☺️
'Swfit' 카테고리의 다른 글
[Realm] 데이터 저장하는 방법(Create) (0) | 2022.04.08 |
---|---|
[Realm] 데이터 불러오는 방법(Read) (2) | 2022.03.30 |
팀 프로젝트-헤리티지(문화 공유 웹/앱 플랫폼) (0) | 2022.03.21 |
TableViewCell 만드는 방법 정리-등록(Register)하기 (0) | 2022.03.18 |
Core Data or Realm? 어떤 것을 선택해야 할까? (0) | 2022.03.17 |