일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- CustomCode
- Pod
- RealmSwift
- 정보처리기사
- SwiftGen
- Codable
- UITableView
- programmers
- pbxfilesystemsynchronizedrootgroup
- JSON
- 정보처리기사 실기 요약본
- IOS
- Xcode
- 정보처리기사 실기
- cocoapods
- 위클리챌린지
- Decodable
- Custom PageViewController
- PageViewController
- swift
- pbxgroup
- 2018 KAKAO BLIND RECRUITMENT
- 프로그래머스
- issecuretextentry
- storybaord
- dynamic height
- JSONSerialization
- 티스토리챌린지
- JSONParser
- parse
- Today
- Total
iOS 개발일기
[Swift] JSONParser - Decodable(1) 본문
Swift에서 JSON 파싱을 위한 방법에는
- JSONSerialization
- Decodable
이 두가지 방법이 있습니다.
오늘은 Decodable을 이용하여 JSON 파싱을 하는 방법에 대해서 알아보겠습니다.
먼저 파싱에 필요한 예제 데이터를 만들어줍시다.
JSON String Example
let jsonString = """
[
{
"user_id" : 1,
"user_name" : "hoon",
"user_age" : 28
},
{
"user_id" : 2,
"user_name" : "joon",
"user_age" : 30
},
{
"user_id" : 3,
"user_name" : "min",
"user_age" : 32
}
]
"""
Decodable을 사용하기 위해서는 Struct 또는 Class를 통해서 모델을 만들 수 있습니다.
여기서도 jsonString의 Key값과 동일한 프로퍼티를 사용하느냐 아니면 Key값과 다른 프로퍼티를 사용하느냐에 따라서
모델에서 초기화를 해주는 방법이 달라지게 됩니다.
먼저 jsonString의 Key값과 동일한 프로퍼티를 사용하는 경우를 살펴보겠습니다.
Struct User Model
struct User: Decodable {
private(set) var user_id: Int
private(set) var user_name: String
private(set) var user_age: Int
}
Class User Model
class User: Decodable {
private(set) var user_id: Int
private(set) var user_name: String
private(set) var user_age: Int
}
이렇게 Struct 또는 Class를 선언해주면 간단하게 완성이 됩니다.
이 모델을 사용하는 방법도 간단한데요.
guard let data = jsonString.data(using: .utf8) else {return}
do {
let users = try JSONDecoder().decode([User].self, from: data)
guard let users = users else {return}
print(users[0].user_name) //hoon
print(users[1].user_name) //joon
print(users[2].user_name) //min
} catch {
print("parse error:", error)
}
이렇게 간단하게 구현을 할 수 있습니다.
그런데 만약 Key값과 모델의 프로퍼티가 다를 경우에는 초기화를 통해서 직접 디코딩 해주어야 합니다.
jsonString의 Key값과 모델의 프로퍼티가 다를 경우에는
Struct User Model
struct User {
private(set) var uid: Int
private(set) var name: String
private(set) var age: Int
}
extension User: Decodable {
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.uid = try container.decode(Int.self, forKey: .uid)
self.name = try container.decode(String.self, forKey: .name)
self.age = try container.decode(Int.self, forKey: .age)
}
private enum CodingKeys: String, CodingKey, CaseIterable {
case uid = "user_id",
name = "user_name",
age = "user_age"
}
}
Struct Model으로 구현을 하실 경우에는 extension으로 Decodable을 구현할 수 있지만
Class Model을 만드실 경우에는 extension으로 Decodable을 구현할 수 없습니다.
Decodable은 protocol이므로 required init을 extension에서 수행할 수 없는 것 같네요?
자세하게 아시는 분이 있으시다면 알려주시면 감사하겠습니다.
Class User Model
class User: Decodable {
private(set) var uid: Int
private(set) var name: String
private(set) var age: Int
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.uid = try container.decode(Int.self, forKey: .uid)
self.name = try container.decode(String.self, forKey: .name)
self.age = try container.decode(Int.self, forKey: .age)
}
private enum CodingKeys: String, CodingKey, CaseIterable {
case uid = "user_id",
name = "user_name",
age = "user_age"
}
}
이렇게 자신이 원하는 프로퍼티명을 사용하여 모델을 만들 수 있습니다.
저는 대부분 이렇게 사용하는 편인거 같네요.
(프로시저로 받는 JSONData의 프로퍼티명들이 마음에 안드는지라...)
이 모델들도 사용하는 방법은 동일합니다.
guard let data = jsonString.data(using: .utf8) else {return}
do {
let users = try JSONDecoder().decode([User].self, from: data)
guard let users = users else {return}
print(users[0].name) //hoon
print(users[1].name) //joon
print(users[2].name) //min
} catch {
print("parse error:", error)
}
여기서, 왜 Struct와 Class로 나누어서 적어놓느냐라고 의문을 가지시는 분들도 계실 것 같습니다만
(저같은 경우에는)
재사용을 자주해야되거나 값을 변경하였을 때 같이 변경되어야 하는 모델이 필요하다면 Class
예를 들면, CollectionView에 Cell별로 모델을 넣어주어야하고 값이 변경될 수 있는 상황이 있을 경우에는
Class로 모델을 생성하는 편입니다.
일회성으로만 사용되거나 값을 변경할 필요가 없는 모델이 필요하다면 Sturct
로 생성해서 사용하는 편입니다.
(제가 하는 방법이 잘못된 경우에는 알려주시면 감사하겠습니다..)
1편은 기본적인 개념과 사용방법에 대해서 알아보았습니다.
조금 더 심화 및 응용부분은 다음 편에서 다루어보도록 하겠습니다. 허허
2편
'iOS > Swift' 카테고리의 다른 글
[Swift] JSONParser - JSONSerialization (0) | 2022.03.16 |
---|---|
[Swift] JSONParser - Decodable(2) (0) | 2022.03.15 |
[Swift] iOS 15, UINavigationBar barTintColor 적용 방법 (0) | 2021.09.28 |
[Swift] String.addingPercentEncoding() 특수문자 인코딩하기 (0) | 2021.03.22 |
[Swift] 스토리보드없이 코드로 rootViewController를 설정하는 방법 (0) | 2020.04.08 |