Codable이란?


A type that can convert itself into and out of an external representation.

자신을 변환하거나 외부 표현(JSON 같은 데이터를 주고 받는 형식)으로 변환할 수 있는 타입이다.

 

또한

Codable은 Decodable과 Encodable을 동시에 채택한 타입이다.

 

Decodable : 자신을 외부표현(external representation)에서 디코딩 할 수 있는 타입

Encodable : 자신을 외부표현(external representation)으로 인코딩 할 수 있는 타입

 

따라서, Codable은 자신을 외부표현으로 디코딩 & 인코딩이 가능한 타입 이라고 생각하시면 될 것 같다

 

Codable은 프로토콜

Codable은 프로토콜이므로 Class, Struct, Enum 에서 모두 사용할 수 있습니다. (이전 Protocol 포스팅에 있음)

그리고 타입에서 Codable을 채택했다는 것은 해당 타입을 serialize / deserialize 할 수 있다는 것

 

struct SomeType{
	var name: String
    var id: Int
}

이라는 구조체가 있다고 가정하자.

해당 타입에 Codable을 채택해보자

struct SomeType: Codable {
	var name: String
    var id: Int
}

이제 SomeType이라는 구조체는 외부표현(JSON형식)으로 변환이 가능한 타입입니다.

 

Encode

JSON으로 만드는 방법

//인코더 생성
let encoder = JSONEncoder()

//인스턴스 생성
let someInstance = SomeType(name: "First", id: 1)

//인코딩해서 jsonData에 저장 
// 1. encode메소드의 리턴타입은 Data
// 2. encode메소드는 throws -> try? 사용 -> try? 사용으로 jsonData는 옵셔널
let jsonData = try? encoder.encode(someInstance)

//Data 형식을 보기 좋게 String으로 변환
if let jsonData = jsonData, let jsonString = String(data: jsonData, encoding: .utf8){
	print(jsonString) // {"name" : "First", "id" : 1}
}

 

주로 주고받을 데이터 형식을 약속할 때, JSON을 사용한다. 하지만 어느 곳을 가도 {"name":"First","id":1} 처럼 가로로 쭉 늘어놓은 데이터로 약속을 하지 않을 것이다. 보통 봐온 JSON형식은 아래와 같다

{
	"name" : "First",
    "id" : 1
}

위처럼 JSONString을 이쁘게 만들 수 있다

//위와 같이 이쁘게 만들어준다
encoder.outputFormatting = .prettyPrinted

//key값을 기준으로 오름차순으로 정렬한다
encoder.outputFormatting = .sortedKeys

//그렇다면 나는 key값을 기준으로 오름차순으로 정렬한 이쁜 데이터를 받고싶어!
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]

 

Decode

JSON을 내가 만든 타입으로 변환하기

주로 서버에 있는 데이터(JSON)을 받아서 내가 저장하고 싶은 타입의 모델에 저장하는 작업을 자주하게 된다.

이때 사용할 수 있는 것이 Codable이다.

 

//디코더 생성
let decoder = JSONDecoder()

//위에서 만든, Encode된 JSON을 Data로 변환
var data = jsonString.data(using: .utf8)

//Data 형식을 내가 만든 모델인 SomeType의 인스턴스로 변환
if let data = data, let someInstance = try? decoder.decode(SomeType.self, from: data){
	print(someInstance.name) // First
    print(someInstance.id) // 1
}

 

 

CodingKey

음... 쉽게 예를 들어보자

struct SomeType: Codable{
	var name: String
    var id: Int
}

위와 같은 타입에 Codable을 채택했다.

근데 넘어오는 데이터 형식이

{
	"name" : "First",
    "identifier" : 1
}

이렇게 넘어온다고 하자

 

내가 생성한 모델의 id와 넘어오는 JSON의 identifier의 "Key"가 다르다 -> 이렇게 되면 

No Value associated with key id 라고 나온다.

 

해결 방법은 2가지가 있다.

  1. JSON형식에 맞춰 모델의 프로퍼티 명을 작성하는 방법
    1. 오류는 없겠지만, 가독성 측면에서 좋지 않다
  2. CodingKey 사용!

CodingKey 사용

struct SomeType: Codable{
	var name: String
    var id: Int
    
    enum CodingKeys: String, CodingKey{
    	case name
        case id = "identifier" // identifier라는 키는 이제부터 id프로퍼티가 담당할거야!
    }
}

 

 

지금까지 Swift에서 모델에서 JSON으로 인코딩, JSON에서 모델로 디코딩 방법과

key값이 다를 때 사용하는 CodingKey에 대해 알아보았다.

 

 

 

 

 

 

 

 

+ Recent posts