개발/Swift
Swift 데이터 감싸져 있는 안에 있는 값 꺼내서 Decode하기
덤벨로퍼
2023. 7. 22. 16:07
{
"identifier": "dsdfdsf",
"name": "james",
"product: {
"expiration_poloicy": {
"expire" : 90
}
}
}
위와 같은 데이터를 서버로부터 받을때
원하는 데이터인 expire는 두번 감싸져 있다.
해당 데이터를 decoding을 하기위해 Entity를 총 세개나 만들어야 원하는 데이터값을 받을수 있을것이다.
struct People: Decodable {
var identifier: String
var name: String
var product: Product
}
struct Product: Decodable {
var expirationPlicy: ExpirationPlicy
//public init(from decoder: Decoder) throws {} ....
}
struct ExpirationPlicy: Decodable {
var expire: Int
//public init(from decoder: Decoder) throws {} ....
}
이렇게 가능하다
하지만 만약 이렇게 엔티티를 여러개 만들고 싶지않고 People 인스턴스안에 expire 데이터를 넣고싶다면
코딩키와 nestedContainer를 사용해 가능하다
struct People: Decodable {
var identifier: String
var name: String
var expire: Int
enum CodingKeys: String, CodingKey {
case identifier
case name
case product
enum Product: String, CodingKey {
case expirationPolicy = "expiration_policy"
enum ExpirationPolicy: String, CodingKey {
case expire
}
}
}
}
코딩키 안에 Product 와 ExpirationPolicy코딩키를 또 만들어주었다.
이제 디코딩을 하려면 nestedContainer 를 사용하면 되는데
let container = try decoder.container(keyedBy: CodingKeys.self)
let productContainer = try container.nestedContainer(keyedBy: CodingKeys.Product.self,
forKey: .product)
nestedContainer 를 통해 Product container를 생성 할수 있다.
이러면 이 컨테이너를 통해 컨테이너 안에 expirationPolicy에 접근 할수 있다.
let expirationPolicyContainer = try productContainer
.nestedContainer(keyedBy: CodingKeys.Product.ExpirationPolicy.self,
forKey: .expirationPolicy)
역시 ExpirationPolicy 안에 접근해야 하기 때문에 똑같이 컨테이너를 생성해주고
self.expire = try expirationPolicyContainer.decode(Int.self, forKey: .expire)
expire 에 결국 접근할수 있게 되었다.
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.identifier = try container.decode(String.self, forKey: .identifier)
self.name = try container.decode(String.self, forKey: .name)
let productContainer = try container.nestedContainer(keyedBy: CodingKeys.Product.self,
forKey: .product)
let expirationPolicyContainer = try productContainer
.nestedContainer(keyedBy: CodingKeys.Product.ExpirationPolicy.self,
forKey: .expirationPolicy)
self.expire = try expirationPolicyContainer.decode(Int.self, forKey: .expire)
}
전체 코드