Codable 정리
Encodable/Decodable
자신을 변환하거나 외부표현으로 변환할 수 있는 타입
- 변환의 의미에 대해 더 생각해 볼 것
구조
typealias Codable = Decodable & Encodable
- Encodable: 외부 표현으로 인코딩할 수 있는 타입
- Decodable: 외부 표현에서 디코딩할 수 있는 타입
- 외부 표현(external representation)은 JSON으로 이해해도 무방
- Codable은 Class, Struct, Enum에서 모두 채택 가능
사용법
- encoding/decoding중에는 에러를 발생시킬 수 있기때문에 반드시 try와 함께 사용
import Foundation
struct Person: Codable {
var name : String
var age : Int
}
let ocean = Person(name: "Ocean", age: 30)
// -------------encoding-------------
// 1. encoder 선언 및 포맷 설정
let encoder = JSONEncoder()
encoder.outputFormatting = [.sortedKeys, .prettyPrinted]
// 2. encode() 메소드를 사용하여, Person 인스턴스를 Data로 encoding
let jsonData = try? encoder.encode(ocean)
// 3. Data를 String으로 변환
if let jsonString = String(data: jsonData!, encoding: .utf8) {
print(jsonString)
// {
// "age" : 30,
// "name" : "Ocean"
// }
}
// -------------decoding-------------
let jsonString = """
{
"name" : "ocean",
"age" : 30,
}
"""
// 1. decoder 선언
let decoder = JSONDecoder()
// 2. String을 Data로 변환
let data = jsonString.data(using: .utf8)
// 3. Data를 Person 인스턴스로 decoding
if let myProfile = try? decoder.decode(Person.self, from: data!) {
print(myProfile.name)
print(myProfile.age)
// ocean
// 30
}
CodingKey
CodingKey: 인코딩/디코딩을 위한 키로 사용할 수 있는 타입
- 선언으로 미리 매칭해놓은 CodingKey를 실제 struct/class/enum의 key처럼 사용할 수 있다
사용법
- String도 같이 채택한 이유: Raw Value타입으로 String을 선택
- JSON에서의 Key는 항상 String이기 때문
// -------------CodingKey-------------
struct Animal: Codable {
var name : String
var age : Int
var height : Int
enum CodingKeys : String, CodingKey {
case name
case age
case height = "tall"
}
}
// CodingKey로 정한 이상, JSON에서 원래의 key(여기서는 height)를 사용할 수 없다
// "height" : 55로 작성시 decoding 실패
let jsonCodingKeyString = """
{
"name" : "crepe",
"age" : 3,
"tall" : 55
}
"""
let decode = JSONDecoder()
// String을 Data로 변환 후, Animal 인스턴스로 decoding
if let data = jsonCodingKeyString.data(using: .utf8), let petProfile = try? decoder.decode(Animal.self, from: data) {
print(petProfile.name)
print(petProfile.age)
print(petProfile.height)
// print(petProfile.tall) // 컴파일 에러
}