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가지가 있다.
- JSON형식에 맞춰 모델의 프로퍼티 명을 작성하는 방법
- 오류는 없겠지만, 가독성 측면에서 좋지 않다
- 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에 대해 알아보았다.
'Swift' 카테고리의 다른 글
[Swift] DI: 의존성 주입 (Dependency Injection) in iOS/Swift (0) | 2021.11.09 |
---|---|
[Swift] Nested JSON Decode (0) | 2021.03.16 |
[Swift] 상속 - 스위프트 언어 및 문법(13) - feat.야곰's Swift Programming (0) | 2021.01.19 |
[Swift] 서브스크립트 - 스위프트 언어 및 문법(12) - feat.야곰's Swift Programming (0) | 2021.01.18 |
[Swift] 모나드 - 스위프트 언어 및 문법(11) - feat.야곰's Swift Programming (0) | 2021.01.18 |