앞서 기초편에서 간단하게 JSON을 파싱하는 법을 알았는데 확장편에서는 마주할 법한 상황을 가정하여 좀 더 자세하게 다뤄 볼 예정이다.
목차
1. Json에 null값이 들어 왔을 때
2. 아예 Key값이 안들어 왔을 때
3. Json안에 Object가 들어 있을 때
4. CordingKeys 사용해보기
Json에 null값이 들어 왔을 때
struct User: Codable {
let name: String
let age: Int
let picture: String
let isActive: Bool
}
우리는 기초편에서 User의 모델을 위와 같이 정의했다. 하지만 이 구조체는 모든 값이 유효할 때만 데이터를 성공적으로 파싱할 수 있다.
{
"name": "이기회",
"age": 77,
"picture": null, // picture가 null로 들어왔다.
"isActive": true,
}
예를들어 json이 위와같이 온다면
이런식의 valueNotFound에러를 마주하고 데이터를 화면에 못 보여주게된다.
이렇게 nullable한 값이 오는 것을 방지하기 위해서는 데이터의 값 타입에 optinal을 추가하여 유연하게 대처 할 수 있게한다.
struct User: Codable {
let name: String
let age: Int
let picture: String? // nullable
let isActive: Bool
}
// UI
Image(user.picture ?? "") // picture
물론 UI에서 nil값 처리를 해주어야한다.
아예 Key값이 안들어 왔을 때
위의 경우는 value가 null로 들어왔지만 이번에는 아예 key가 없을 경우이다.
실무에서는 레거시코드를 제거할 때 이런 이런 오류가 발생할 수 있다.
{
"name": "이기회",
// age가 사라졌다.
"picture": null,
"isActive": true,
}
json이 이런 식으로 들어온다면
위와 같은 keyNotFound 에러를 마주하게 된다.
이것도 역시 값 타입을 optinal로 바꾸어주면 해결된다.
struct User: Codable {
let name: String
let age: Int?
let picture: String?
let isActive: Bool
}
// UI
Text("\(user.age ?? 100)") // age
Json안에 Object가 들어 있을 때
{
"name": "이기회",
"picture": null,
"isActive": true,
"location": {
"city": "Seoul",
"country": "Korea",
"coordinates": {
"latitude": "31.7581",
"longitude": "-58.1757"
}
}
}
이번에는 Json value안에 또 다른 Json이 있을 경우에 Model을 구현해보자
struct User: Codable {
let name: String?
let age: Int?
let picture: String?
let isActive: Bool?
let location: Location? // Codable을 준수하는 구조체
}
struct Location: Codable {
let city: String?
let country: String?
let coordinates: Coordinates? // Codable을 준수하는 구조체
}
struct Coordinates: Codable {
let latitude: String?
let longitude: String?
}
만들고자하는 Object를 새로 구조체를 만들어서 위와같이 사용하면 된다.
CordingKeys 사용해보기
지금까지는 Json의 key이름을 그대로 swift에서 사용했다. 하지만 그러고 싶지 않을 경우에는 어떻게 할까?
{
"name": "이기회",
"picture": null,
"isActive": true,
"location": {
"city": "Seoul",
"country": "Korea",
"coordinates": {
"latitude": "31.7581",
"longitude": "-58.1757"
}
},
"user_gender": "male"
}
Json key로 user_gender로 주었지만 Swift 변수명으로는 적합하지 않다.
struct User: Codable {
let name: String?
let age: Int?
let picture: String?
let isActive: Bool?
let location: Location?
let gender: String?
enum CodingKeys: String, CodingKey {
case name
case age
case picture
case isActive
case location
case gender = "user_gender"
}
}
이 경우에는 CodingKey를 준수하는 CodingKeys라는 열거형을 만듭니다. (단어 맨 뒤 s확인!!)
그 모델의 변수명을 그대로 case에 쓰고 파싱할 이름을 rawValue에 넣어 사용하면 됩니다.
그러면 위와 같이 gender에 male이 성공적으로 들어오는 것을 확인 할 수 있습니다.
실전 Tip.
이제 배운 것을 바탕으로 https://randomuser.me/api/의 Json을 파싱해보자
{
"results": [
{
"gender": "male",
"name": {
"title": "mr",
"first": "brad",
"last": "gibson"
},
"location": {
"street": "9278 new road",
"city": "kilcoole",
"state": "waterford",
"postcode": "93027",
"coordinates": {
"latitude": "20.9267",
"longitude": "-7.9310"
},
"timezone": {
"offset": "-3:30",
"description": "Newfoundland"
}
},
"email": "brad.gibson@example.com",
"login": {
"uuid": "155e77ee-ba6d-486f-95ce-0e0c0fb4b919",
"username": "silverswan131",
"password": "firewall",
"salt": "TQA1Gz7x",
"md5": "dc523cb313b63dfe5be2140b0c05b3bc",
"sha1": "7a4aa07d1bedcc6bcf4b7f8856643492c191540d",
"sha256": "74364e96174afa7d17ee52dd2c9c7a4651fe1254f471a78bda0190135dcd3480"
},
"dob": {
"date": "1993-07-20T09:44:18.674Z",
"age": 26
},
"registered": {
"date": "2002-05-21T10:59:49.966Z",
"age": 17
},
"phone": "011-962-7516",
"cell": "081-454-0666",
"id": {
"name": "PPS",
"value": "0390511T"
},
"picture": {
"large": "https://randomuser.me/api/portraits/men/75.jpg",
"medium": "https://randomuser.me/api/portraits/med/men/75.jpg",
"thumbnail": "https://randomuser.me/api/portraits/thumb/men/75.jpg"
},
"nat": "IE"
}
],
"info": {
"seed": "fea8be3e64777240",
"results": 1,
"page": 1,
"version": "1.3"
}
}
이 API는 위와같이 Json을 내려준다고 한다. 이제 이것을 Swift 구조체로 만들어야 되는데 필요한 값만 쏙쏙 빼서 만들어도 되지만 Json을 struct로 바꿔주는 갓갓 퀵타입을 사용하자..!
result안에 있는 데이터만 복사해서 붙여넣기하면 이렇게 알아서 다 만들어준다
이것을 그대로 복사 붙여넣기하면된다
'iOS > SwiftUI' 카테고리의 다른 글
SwiftUI와 상태관리 (0) | 2022.04.03 |
---|---|
SwiftUI에서 스켈레톤 UI 적용하기 (0) | 2022.02.20 |
[SwiftUI] EnvironmentObject / ObservedObject / StateObject (0) | 2022.01.30 |
[Swift] Codable로 JSON파싱하기 -기초- (0) | 2022.01.30 |
[SwiftUI] PencilKit을 사용해 캔버스 만들기 (0) | 2022.01.15 |