Codable이란
codable은 encodable과 decodable을 합친 것으로 JSON을 쉽게 Serialize, Deserialize해서 읽어주는 역할을 한다.
일반적인 서버 API 통신시 JSON 형태를 사용하므로 이 때 유용하게 사용된다.
Encodable
Encoding은 어떤 데이터(swift에서 구조체, 클래스 등..)을 JSON 형태로 변환시켜준다. 보통 JSON을 읽어오는 Decodable을 주로 더 많이 사용하긴 한다.
struct Developer: Encodable {
let name: String
let role: String
}
let peppermint100 = Developer(name: "peppermint", role: "backend")
let data = try? JSONEncoder().encode(peppermint100)
let json = try? JSONSerialization.jsonObject(with: data!, options: .fragmentsAllowed)
print(json)
이렇게 encode
를 통해 bytedata로 변환 후 JSONSerialization
을 통해 json 문자열로 변경할 수 있다.
Decodable
Decodable은 JSON 문자열을 Swift의 데이터 구조로 바꾸어준다. 구조체, 클래스, 열거형 모두 가능하다.
struct Developer: Decodable {
let name: String
let role: String
}
let data = """
{
"name" : "peppermint100",
"role" : "backend"
}
""".data(using: .utf8)!
let result = try? JSONDecoder().decode(Developer.self, from: data)
print(result!)
Coding Key
API 응답의 파라미터 이름으로 가끔 Swift에서 사용하는 카멜 케이스가 아닌 스네이크 케이스로 오는 경우가 있다. 혹은 단순히 파라미터 이름 값이 마음에 들지 않거나
이런 경우 Coding Key
를 통해 파라미터 이름을 바꿔서 스위프트 데이터에 넣을 수 있다.
struct Developer: Codable {
let name: String
let role: String
enum CodingKeys: String, CodingKey {
case name
case role = "role_1"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = (try? values.decode(String.self, forKey: .name)) ?? ""
role = (try? values.decode(String.self, forKey: .role)) ?? ""
}
}
let data = """
{
"name" : "peppermint100",
"role_1" : "backend"
}
""".data(using: .utf8)!
let result = try? JSONDecoder().decode(Developer.self, from: data)
print(result!)
JSON에는 role_1
으로 되어 있지만 Developer 구조체의 role
에 매핑되도록 CodingKeys를 지정할 수 있다.
또 decoder
를 통한 초기화 메소드를 작성함으로서 JSON에 값이 없는 경우에도 에러를 띄우지 않고 디폴트 값(위의 경우 빈 문자열 "")을 지정할 수도 있다.