ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Swift 데이터 감싸져 있는 안에 있는 값 꺼내서 Decode하기
    개발/Swift 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)
    }
    

    전체 코드

    댓글

Designed by Tistory.