본문 바로가기

iOS 앱 개발자 프로젝트/iOS 숙련

[iOS] Decodabe, Encodable, Codable

2024년 4월 13일 토요일

 

Make your data types encodable and decodable for compatibility with external representations such as JSON.

 

Encoding and Decoding Custom Types | Apple Developer Documentation

Make your data types encodable and decodable for compatibility with external representations such as JSON.

developer.apple.com


 

📌   Decodable 프로토콜

 

Decodable 프로토콜과 CodingKeys 열거형을 사용하면,

JSON과 같은 외부 데이터 소스로부터 데이터를 구조체나 클래스로 변환할 때,

데이터의 키 이름과 구조체의 프로퍼티 이름이 다를 경우 유연하게 매핑할 수 있다. 

 

User 구조체 디코딩 예시 ▽ 

struct User: Decodable {
    let id: Int
    let name: String
    
		public enum CodingKeys: String, CodingKey {
      case id = "key"
      case name
    }

    // Decoding 
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try container.decode(Int.self, forKey: .id)
        name = try container.decode(String.self, forKey: .name)
    }
}

 

△ CodingKeysinit(from:) 메서드 

 

·  CodingKeys: CodingKeys 열거형은 외부 데이터의 키 이름과 구조체의 프로퍼티 이름을 매핑한다. JSON에서는 key라는 이름으로 제공되는 데이터를 구조체에서 id라는 프로퍼티로 사용하고 싶을 때, case id = "key"와 같이 선언한다.

 

·   init(from:) 메서드: Decoder 인스턴스로부터 필요한 데이터를 추출해 User 인스턴스를 초기화. container(keyedBy:) 메서드를 사용하여 CodingKeys에 정의된 키를 기반으로 데이터를 추출하고, decode(_:forKey:) 메서드로 각 프로퍼티에 해당하는 데이터를 디코딩한다.

 

 

 

📌   Encodable 프로토콜

 

Encodable 프로토콜을 사용해 구조체나 클래스의 인스턴스를 JSON과 같은 외부 데이터 형식으로 변환할 수 있다.

CodingKeys 열거형으로 구조체 프로퍼티 이름과 외부 데이터 소스의 키 이름을 매핑해준다.

 

User 구조체 인코딩 예시 ▽ 

struct User: Encodable {
    let id: Int
    let name: String

		public enum CodingKeys: String, CodingKey {
      case id = "key"
      case name
    }

    // Encodable 프로토콜을 준수하기 위한 커스텀 인코딩 로직
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(id, forKey: .id)
        try container.encode(name, forKey: .name)
        // 다른 프로퍼티들도 인코딩 가능
    }
}

 

△  CodingKeys encode(to:) 메서드

 

·   CodingKeys: CodingKeys 열거형은 구조체의 프로퍼티 이름과 외부 데이터의 키 이름을 매핑한다. 구조체는 id라는 프로퍼티를 사용하지만, 외부 데이터는 key로 이름 데이터를 인코딩하고 싶을 때, case id = "key"와 같이 선언한다.

 

·   encode(to:) 메서드: Encoder 인스턴스로 User 인스턴스 데이터를 외부 데이터 형식으로 인코딩. container(keyedBy:) 메서드를 사용하여 CodingKeys에 정의된 키를 기반으로 데이터를 인코딩하고, encode(_:forKey:) 메서드로 각 프로퍼티에 해당하는 데이터를 인코딩한다.

 

 

 

📌   Codable 프로토콜

 

Codable 프로토콜은 두 하위 프로토콜, EncodableDecodable 을 결합한 것으로,

데이터 모델을 JSON과 같은 외부 데이터 형식으로 인코딩하거나 디코딩할 수 있게 해주는 방법을 제공한다.

public typealias Codable = Decodable & Encodable

 

 

User 구조체 인코딩과 디코딩 예시  ▽ 

struct User: Codable {
    let id: Int
    let name: String

		public enum CodingKeys: String, CodingKey {
      case id = "key"
      case name
    }

    // Encodable 프로토콜을 준수하기 위한 커스텀 인코딩 로직
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(id, forKey: .id)
        try container.encode(name, forKey: .name)
        // 다른 프로퍼티들도 인코딩 가능
    }

    // Decoding - 디코딩
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try container.decode(Int.self, forKey: .id)
        name = try container.decode(String.self, forKey: .name)
    }
}

 

CodingKeys와 커스텀 인코딩/디코딩 로직

 

·   CodingKeys: 구조체의 프로퍼티 이름과 외부 데이터 소스의 키 이름을 매핑합니다. 구조체에서는 id라는 프로퍼티를 사용하고, 외부 데이터에서는 key라는 이름으로 인코딩할 때, case id = "key"와 같이 선언하여 JSON 키 이름과 Swift 모델의 프로퍼티 이름이 다를 때 유연하게 대응한다.

 

·   encode(to:) 메서드: Encoder 인스턴스를 사용하여 User 인스턴스의 데이터를 외부 데이터 형식으로 인코딩. container(keyedBy:) 메서드를 사용하여 CodingKeys에 정의된 키를 기반으로 데이터를 인코딩하고, encode(_:forKey:) 메서드로 각 프로퍼티에 해당하는 데이터를 인코딩한다.

 

·   init(from:) 메서드: Decoder 인스턴스를 사용하여 외부 데이터 형식에서 User 인스턴스를 디코딩. container(keyedBy:) 메서드로 CodingKeys를 사용하여 데이터를 디코딩하고, decode(_:forKey:) 메서드로 각 프로퍼티에 해당하는 데이터를 디코딩한다.