Decoding시 key가 없는 경우

Lena·2021년 7월 4일
2
post-custom-banner

다음과 같이 struct를 정의하고,

struct Room: Decodable {
    let hotelID: Int
    let title: String
    let price: Double
    let wishlist: Bool
    let longitude: Double
    let latitude: Double
    let rate: Int
    let options: [String]
    let img: String
}

json data를 모델 객체로 decoding 할 때 해당하는 key가 없는 경우,
init(from decoder: Decoder)을 직접 구현해서 처리할 수 있다.

// 다음과 같이 데이터가 내려올 경우
[
    {
        "hotelId": 1,
        "title": "title",
        "price": 100,
        "wishlist": false,
    }
]

init(from decoder: Decoder) throws {
  // 구현부를 작성.
}

CodingKeys를 정의하고, decodeIfPresent를 이용해 key가 없을 경우에 기본 값을 정의한다.

enum CodingKeys: String, CodingKey {
        case hotelID = "hotelId"
        case title, price, wishlist, longitude, latitude, rate, options, img
    }
    
init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    hotelID = try container.decode(Int.self, forKey: .hotelID)
    title = try container.decode(String.self, forKey: .title)
    price = try container.decode(Double.self, forKey: .price)
    wishlist = try container.decode(Bool.self, forKey: .wishlist)
    longitude = try container.decodeIfPresent(Double.self, forKey: .longitude) ?? 0
    latitude = try container.decodeIfPresent(Double.self, forKey: .longitude) ?? 0
    rate = try container.decodeIfPresent(Int.self, forKey: .longitude) ?? 0
    options = try container.decodeIfPresent([String].self, forKey: .options) ?? []
    img = try container.decodeIfPresent(String.self, forKey: .options) ?? ""
}

decodeIfPresent 대신 decode를 사용할 수도 있다.

longitude = (try? container.decode(Double.self, forKey: .longitude)) ?? 0

decodeIfPresent는 optional, decode은 non-optional 타입을 리턴한다.

decodeIfPresent
Return Value: A decoded value of the requested type, or nil if the Decoder does not have an entry associated with the given key, or if the value is a null value.

정리🙃.
model(struct, class)의 속성을 optional로 정의하고 싶지 않으면서,
decoding 시 keyNotFound error를 핸들링하기 위해
init(decoder:) 구현부를 직접 작성할 수 있다.


ref.
https://jinnify.tistory.com/71
https://zeddios.tistory.com/577

post-custom-banner

0개의 댓글