[iOS] Swift에서의 Codable

gaeng2y
5 min readJun 12, 2022

--

안녕하세요! 갱입니다 🫡

오늘은 Codable입니다 ㅎㅎ

Codable에 관해서는 많은 포스팅이 있고 참고자료도 많지만 제가 포스팅하는 이유는 제가 공부했던 내용 및 복습의 차원에서 포스팅하려고 합니다

우선 Codable이 뭔지 알아봐야죠?

Codable

정의: 외부 표현으로 또는 외부 표현으로 변환할 수 있는 형식입니다.
typealias Codable = Decodable & Encodable

제 포스팅을 읽고 계신 분이라면 이 녀석을 어디에 사용하려고 하는 지는 잘 아실거라 예상하며 간단하게 설명하고 넘어가겠습니다.

Codable이란 JSON 형식의 데이터를 디코딩(Decodable) / 저희가 만든 Model을 JSON 형식으로 인코딩(Encodable) 할 수 있게 만들어주는 프로토콜입니다

Codable은 프로토콜이기 때문에 구조체, 클래스, 열거형에 채택이 가능합니다

, Codable을 채택했다는 건 구조체, 클래스, 열거형을 인코딩, 디코딩을 할 수 있다는 것을 의미하기도 합니다.

그러면 코드를 보며 살펴보져!

저희는 Book이라는 구조체를 만들었습니다. 요 구조체에 Codable을 채택해 볼까요?

요런 식으로 Codable이라는 프로토콜을 채택해주면 됩니다..(간단)

그렇다면 이제 Book을 인코딩해볼까요?

Encode

인코딩은 JSONEncoder를 이용하여 인코딩할 수 있습니다.

위의 코드로 콘솔을 보면 data라 어떤 내용인지 안보일겁니다… 그러니 우리는 해당 data를 String으로 변환해서 확인해보죠

Decode

마찬가지로 디코딩은 JSONDecoder를 이용하여 디코딩할 수 있습니다.

Optional & Nullable key

특정 필드 값이 Optional 하거나, Nullable 한 키인 경우에는 아래와 같이 구조체를 정의할 수 있습니다.

근데 기본 값을 할당하고 싶은 경우에는 값을 주면 된다!

CodingKey

API Response 데이터가 스네이크 케이스(ex. is_soldout)를 사용하는 경우에는 Swift 이름 규칙(카멜 케이스)에 맞지 않기 때문에 이런 경우에는 CodingKey를 사용해주면 됩니다

정의: 인코딩 / 디코딩을 위한 키로 사용할 수 있는 타입

JSON 데이터의 key와 사용하고자하는 key가 매핑될 수 있도록 CodingKey를 채택한 열거형을 작성해주면 됩니다

Handle date

JSON에는 날짜를 나타내는 데이터 유형이 없으므로 클라와 서버가 동의한 형식(일반적으로는 ISO8601)으로 디코딩하게 됩니다

요렇게 정의하고 디코드를 해보면 “typeMismatch” 에러가 발생할 것입니다

decoder.dateDecodingStrategy = .iso8601

decoder에 DateDecodingStrategy 프로퍼티의 값을 변경해주면 date 형태로 잘 변환될 것입니다.

Wrapper Keys

API Response가 아래와 같이 Wrapper Key를 포함하는 경우에는

{
"success": Bool,
"data" : [Book]
}

Response에 대한 새로운 타입을 만들어 주면 됩니다.

Decode type as Enum

위의 코드처럼 Book 구조체의 genre가 Genre 열거형에서 하나의 값을 가지는 경우에는 열거형 또한 Codable을 채택하면 그대로 타입을 적용할 수 있습니다.

만약, 열거형에서 정의하지않은 케이스가 있는 경우,

아래와 같이 Unknown이라는 케이스를 추가로 선언하고,

init(from:)을 정의하여 일치하는 값이 없는 경우 Unknown으로 defaultValue를 주어 오류를 방지할 수 있습니다.

Decoding nested JSON

Api Response가 중첩된 구조로 오는 경우가 있죠

이렇게 Api Response 데이터의 구조를 바꾸고싶은 경우, Codable 프로토콜을 커스텀할 수 있습니다.

아래와 같은 JSON 데이터를

{
"title" : "test book",
"author" : "Kyle yang",
"price": 25000,
"bookstore": {
"place" : "교보문고",
"soldout" : false
}
}

구조체로 디코딩하는 모델을 작성해보면

이제 decode을 할 수 있도록 init(from:) 을 정의해줍시다

위치는 Book 내부

Encoding nested JSON

그렇다면 반대로 내가 갖고있는 모델을 중첩된 JSON 데이터로 변환을 해보자!

디코딩할 때와 반대로 컨테이너에 값을 인코딩 해주면 됩니다

이 때 컨테이너는 변경할 수 있는 mutable 프로퍼티이므로 당연히 변수(var)로 선언해줘야 합니다

마찬가지로 위치는 Book 내부

마무리

여기까지 Swift의Codable 프로토콜의 기본 사용법을 알아보았습니다!

Codable이 나오기 전까지는 JSON을 다루기 위해 SwiftyJSON 같은 라이버리르를 사용하는 등 어려웠던 점이 많았지만

Codable을 사용하면 손쉽게 인/디코딩을 할 수 있으니 유용한 기능인 것 같네요

모두들 Codable 쓰세요 (사실 나빼고 다알고 있었음 😢)

Reference

--

--