반응형
CodingKeys
CodingKeys
struct Model: Codable {
var name: String
var number: Int
}
// JSON File
{
"myName" : "Inu",
"number" : 5
}
- 우리는 주로 Codable Protocol을 채택하여 모델을 구성합니다.
- 이 때 구현하려는 구조체의 속성과 JSON Data의 Key값이 일치해야 정상적으로 Decoding됩니다.
- 그런데 사실 구현하려는 구조체의 속성과 JSON Data의 Key값이 일치하는 경우는 거의 없습니다.
- 위의 예시의 name과 myName처럼 다른 것이 일반적입니다.
- 이 때 사용되는 것이 CodingKeys 입니다.
struct Model: Codable {
var name: String
var number: Int
enum CodingKeys: String, CodingKey {
case name = "myName"
case number
}
}
- mapping될 속성을 CodingKeys 열거형에 추가합니다.
- CodingKeys 열거형은 CodingKey Protocol을 채용해야 합니다.
- mapping이 달라지는 속성의 rawValue로 필요한 JSON Data의 Key값을 입력합니다.
Custom Encoding, Decoding
- 인코딩 혹은 디코딩 시점에 값을 검증하거나 제약을 주고 싶을 경우 사용합니다.
- 기본으로 제공되는 인코딩 및 디코딩 객체에 제공되는 속성이나 CodingKeys로는 원하는 결과를 만들 수 없다면 이를 활용해야 합니다.
struct Model: Codable {
var name: String
var number: Int
var realName: String?
func encode(to encoder: Encoder) throws {
var container = encoder.contatiner(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
guard (0...10).contains(number) else { throw EncodingError.invalidRange }
try container.encode(number, forKey: .number)
try container.encodeIfPresent(realName, forKey: .realName)
}
}
- encoding 처리된 데이터는 encoder 내부에 컨테이너 형태로 저장되기 때문에 먼저 해당 container를 가져옵니다.
- 이는 CodingKey 열거형에 존재하는 Key값과 속성을 매핑할 수 있는 container입니다.
- container.encode를 통해 내부 속성을 Key값과 매핑시켜 저장합니다.
- guard 문을 통해 범위를 확인하고 범위에 해당하지 않을 경우 에러를 방출할 수 있습니다. (EncodingError.invalidRange는 직접 선언한 Error 입니다.)
- optional 값의 경우 encodeIfPresent를 사용합니다.
struct Model: Codable {
var name: String
var number: Int
var realName: String?
init(from decoder: Decoder) throws {
let container = decoder.contatiner(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
number = try container.decode(Int.self, forKey: .number)
guard (0...10).contains(number) else { throw EncodingError.invalidRange }
realName = try container.decodeIfPresent(String.self, forKey: .realName)
}
}
- encoder와 마찬가지로 container를 가져옵니다.
- container.decode를 통해 원하는 key의 값을 원하는 타입으로 받아올 수 있습니다.
- guard 문을 통해 범위를 확인하고 범위에 해당하지 않을 경우 에러를 방출할 수 있습니다. (EncodingError.invalidRange는 직접 선언한 Error 입니다.)
- optional 값의 경우 decodeIfPresent를 사용합니다.
반응형
'🍎 Apple > Swift' 카테고리의 다른 글
[Swift] URLSession Cahce Policy (1) | 2022.05.18 |
---|---|
[Swift] URL Loading System (0) | 2022.05.12 |
[Swift] JSON Encoding / Decoding (0) | 2022.05.12 |
[Swift] ATS (App Transport Security) (0) | 2022.05.12 |
[Swift] 순열과 조합 구현 (2) | 2022.04.25 |