Swift에서의 네트워크 통신 이해하기(.feat Decodabe, Encodable, Codable)(2/2)
Decodabe, Encodable, Codable 이해하기
Decodable 프로토콜
Decodable 프로토콜은 데이터를 객체로 디코딩할 때 사용됩니다. 즉, 외부 데이터(JSON)를 Swift의 데이터 모델로 변환하는데에 필요한 프로토콜입니다.
**Decodable**을 준수하는 객체는 외부 데이터를 해석하고 그 데이터를 객체의 프로퍼티로 매핑할 수 있어야 합니다.
이곳에서 CodingKeys 는 디코딩 할 때, 프로퍼티들에 대한 매핑을 제공하는 역할을 합니다. 아래 예시에서는, id라는 프로퍼티의 디코딩 키를 key로, name 프로퍼티의 디코딩 키를 프로퍼티 이름과 동일하게 지정한 예시입니다.
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)
}
}
Encodable 프로토콜
Encodable 프로토콜은 객체를 데이터로 인코딩할 때 사용됩니다. 즉, Swift의 데이터 모델을 외부 데이터(JSON)로 변환하는데에 필요한 프로토콜입니다.
**Encodable**을 준수하는 객체는 객체의 프로퍼티를 외부 데이터 형식(JSON)으로 인코딩할 수 있어야 합니다.
이곳에서 CodingKeys 는 인코딩 할 때, 프로퍼티들에 대한 매핑을 제공하는 역할을 합니다. 아래 예시에서는, id라는 프로퍼티의 인코딩 키를 key로, name 프로퍼티의 인코딩 키를 프로퍼티 이름과 동일하게 지정한 예시입니다.
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)
// 다른 프로퍼티들도 인코딩 가능
}
}
Codable 프로토콜
**Codable** 프로토콜은 두 가지 하위 프로토콜, **Encodable**과 Decodable 을 결합한 것입니다.
public typealias Codable = Decodable & Encodable
외부 데이터(JSON)를 Swift의 데이터 모델로 변환, Swift의 데이터 모델을 외부 데이터(JSON)로 변환을 모두 수행하여야 할 때에, Codable 프로토콜을 사용할 수 있습니다.
이곳에서 CodingKeys 는 인코딩/디코딩 할 때, 프로퍼티들에 대한 매핑을 제공하는 역할을 합니다. 아래 예시에서는, id라는 프로퍼티의 인/디코딩 키를 key로, name 프로퍼티의 인/디코딩 키를 프로퍼티 이름과 동일하게 지정한 예시입니다.
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)
}
}