직렬화(Encode)와 역직렬화(Decode)

Created by
  • 한결

직렬화와 역직렬화

직렬화 - Serialize
encoding 과정이라고 하고, 우리 프로젝트 코드에만 있는 타입을 외부에서 인지할 수 있는 코드화 시키는 과정이다.
Swift의 Class처럼 참조 타입인 경우 저장된 데이터가 메모리의 주소를 기억하고 있기 때문에, 외부에 이 데이터를 전달하고자 하거나 외부에서 이 데이터를 쓰려고 하면 이해할 수 있는 값 (타입)으로 변환이 필요하다.
역직렬화 - Deserialize
decoding 과정이라고 하고, 외부에서 넘어오는 데이터(ex. JSON 형식의 문자형 데이터)를 내부 프로젝트에서 인지할 수 있는 형태로 코드화 시키는 과정이다.
직렬화된 데이터를 다시 사용하기 위해서 디코딩 과정이 반드시 필요하다.

Codable

이름 그대로 코드로 활용할 수 있게끔 만들어주는 프로토콜이다.
외부와의 데이터 상호작용을 위해 encodable, decodable 하게 도와준다.
Swift 공식 문서에는 Codable이 Decodable과 Encodable에 대한 typealias로 되어있다.
즉, 두 경우가 각각 필요한 경우에도 Codable을 타입이나 프로토콜, 제네릭의 타입 제어자 등으로 활용할 수 있다.
다만, 데이터를 직렬화/역직렬화 모두 해야하는 상황이 굳이 아니라면 Decodable, Encodable을 각각 사용하는게 더 좋을 것 같다.
Decodable
역직렬화(decoding)를 도와주는 프로토콜
서버나 외부 API를 통해 넘어오는 JSON과 같은 구조화된 문자열 데이터에서 key-value type 형태를 정확하게 맵핑하여, 앱 내부에서 구조체와 같은 형태로 사용할 수 있게 해준다.
그렇기 때문에 키에 대한 정확한 맵핑, 값에 대한 정확한 타입 정의가 필요하다.
개발자의 오타나 부정확한 타입 명시로 데이터가 원하는 형태로 역직렬화 되지 않을 수 있다.
let JSONExample_USER = """ { "userName": "username", "userId": 1238120 } """ struct Users: Decodable { let name: String let uuid: Int enum CodingKeys: String, CodingKey { case name = "userName" case uuid = "userId" } } func jsondecoding() { guard let data = JSONExample_USER.data(using: .utf8) else { fatalError("JSON 데이터 가지고 오기 실패") } do { let data = try JSONDecoder().decode(Users.self, from: data) dump(data) } catch { print(error) } } jsondecoding()
CodingKeys라고 하는 열거형을 Decodable한 구조체에서 정의하여 우리가 활용하고자 하는 커스텀하여 사용할 수 있다.
주의할 점은, 이미 구조체에 선언되어 있는 모든 멤버를 (커스텀 하지 않더라도) CodingKeys 열거형에 케이스로 구분해야 한다는 것이다.