본문 바로가기

카테고리 없음

Swift Codable

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에 값이 없는 경우에도 에러를 띄우지 않고 디폴트 값(위의 경우 빈 문자열 "")을 지정할 수도 있다.