Codable 프로토콜은 JSON 또는 Property List와 같은 데이터의 직렬화 및 역직렬화 프로세스를 간소화하기 위해 Swift에서 도입되었습니다. 이전에는 이를 위해 수동으로 파싱을 구현해야 했으며, 이는 많은 작업을 요구하고 오류에 취약하며 읽기가 어려웠습니다. 이 프로세스의 자동화는 더 안전하고 간결한 코드를 개발할 수 있게 해주었습니다.
문제는 자동으로 Codable을 적용할 경우 모든 속성이 또한 Codable이어야 하며, 이 체인의 어떤 위반 사항이 있을 경우 명시적인 디코딩 및 인코딩 메서드를 구현해야 한다는 것입니다. 또한 구조체 및 상속이 있는 클래스, 키 매핑을 사용자 지정할 때의 특성이 있습니다.
해결책은 간단한 모델에 대해 Codable을 사용하고 어떤 속성이 직렬화되어야 하는지를 엄격하게 살피며, 복잡한 모델의 경우 encode(to:) 및 init(from:) 메서드를 구현하고 CodingKeys를 사용하여 키 매핑을 수행하는 것입니다.
코드 예:
struct User: Codable { let id: Int let name: String let email: String? enum CodingKeys: String, CodingKey { case id case name = "full_name" case email = "contact_email" } }
주요 특징:
상속이 있는 클래스와 자식의 고유 속성이 Codable을 사용해 자동으로 올바르게 직렬화될 수 있을까요?
아니요, Swift는 상속이 있는 클래스의 경우 자식 클래스에서 encode(to:) 및 init(from:)을 수동으로 구현해야 하며, 그렇지 않으면 부모 및 자식의 속성이 올바르게 직렬화되지 않습니다. 예:
class Animal: Codable { let species: String } class Dog: Animal { let breed: String enum CodingKeys: String, CodingKey { case breed } required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) breed = try container.decode(String.self, forKey: .breed) try super.init(from: decoder) } override func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(breed, forKey: .breed) try super.encode(to: encoder) } }
구조체의 속성이 private으로 표시되고 자동 Codable이 사용될 경우 어떻게 됩니까?
속성이 private이고 명시적인 CodingKeys로 var/let으로 선언되지 않은 경우, 해당 속성은 직렬화되거나 역직렬화되지 않습니다. 따라서 private 속성에는 반드시 CodingKeys를 선언하고 필요할 경우 이 열거형에 포함시켜야 합니다.
오직 디코딩만을 위해 Codable을 구현할 수 있을까요?
네, 이를 위해 init(from:)만 구현하고 타입을 Codable 대신 Decodable 프로토콜에 따르게 하면 됩니다.
struct ReadOnlyModel: Decodable { let id: Int }
** 부정적인 케이스
개발자가 모델에 계산 속성을 추가하면서 자동 Codable 처리를 기대하며 사용자 지정 encode 및 decode 메서드를 구현하지 않았습니다.
장점:
단점:
** 긍정적인 케이스
개발자가 복잡한 경우에 대해 사용자 지정 CodingKeys 및 사용자 지정 encode/decode 메서드를 구현하여 속성이 키와 일치하지 않거나 계산된 필드가 있을 경우, 상속이 적용됩니다.
장점:
단점: