Search
Duplicate

(Swift) Codable 그리고 Encoding, Decoding

간단소개
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
Swift
Scrap
태그
9 more properties
SwiftUI 튜토리얼의 단점은 설명을 마치 우리 교수님처럼 한다는 것이다.. "일단 따라해 그리고 알아서 공부해 와"
.....?
SwiftUI 튜토리얼을 보다보면, 너무나도 당연하게 설명없이 지나가는 부분이 있다. 처음엔 그냥 넘어가면 되나보다 하고 의심없이 넘어가는데 나중에 보면 해당 부분이 이해가 안돼서 뒷 내용 까지도 꼬이는 경우가 발생한다.
가장 큰 어려움이 KeyPath였다. 오늘 정리할 Codable은 뒷 단계를 진행하지 못해서라기 보단, 너무 많이 쓰이는데 설명이 단 한줄도없어서 너무 궁금한나머지 찾아보게 되었다...ㅎㅎ
KeyPath에 대해 정리된 글을 보고싶다면..?
이번 포스팅은 Zedd님의 포스팅을 보며 따라하는 과정을 적은 글입니다.

Codable이 뭘까?

Codable을 공부하면서 내가 아직 개발에 대한 전반적인 이해나 용어에 대한 인지가 부족하다는 것을 많이 깨달았다. 익숙한 단어인데 막상 설명하라고 하면 한마디도 못꺼내는 현 상황...ㅜㅜ 열심히 공부해야지
페이지만 넘기면 나오는 Hashable, Codable... 이게 뭐야 프로토콜인가? Codable... 코드로 쓸 수 있는..? 이 아니고.. Apple Documentation에 나오는 정의를 살펴보자
Codable은 자기 자신을 변환하거나 외부 표현으로 변할 수 있는 타입이라고 나온다.
그런데 타입이 엥..? Type Alias..? 프로토콜이 있어야 할 자리에 Type Alias가 있다니!
그렇다면 우리는 Codable이 프로토콜들로 이루어진 Alias인 것을 눈치채야 한다!(물론 나는 눈치 못챘다ㅎㅎ)
typealias Codable = Decodable & Encodable
Swift
복사
Codable은 Decodable과 Encodable을 동시에 준수하는 타입이라고 할 수 있다. 정의를 살펴보면 각각 프로토콜로 정의 되어 있는 것을 볼 수 있다!
그렇다면 Decodable과 Encodable은 뭘까?
간단하게,
Encodable은 자신 → 외부표현으로
Decodable은 외부표현 → 자신으로
변환할 수 있는 타입이다!
그렇다면 Encoding, Decoding에서 나오는 외부표현이란?
external representations "such as JSON"
우리가 흔히 아는 JSON과 같은 것들이라고 보면 되겠다!

Codable, 어떻게 사용할까?

그렇다면 이 Codable, 어떻게 사용할까?
Apple Documentation에서는 Encoding과 Decoding이 모두 필요한 경우에 채택하여 사용하라고 되어있다. 그렇다면 예제를 통해서 Encoding과 Decoding을 시도해보자!
아래와 같은 구조체가 있다고 생각해보자.
struct Dinner { var menu: String var price: Int }
Swift
복사
Docs에 따르면, codable type을 만들기 가장 쉬운 방법은 이미 Codable을 만족하는 타입으로 프로퍼티를 선언하는 것이라고 되어있다. 예를들면 기본 라이브러리인 String, Int, Double과 같은 것, 그리고Foundation 타입인 Date, Data, URL 등이 있다.
이제 Codable을 채택해보자!
struct Dinner: Codable { var menu: String var price: Int }
Swift
복사
이제 Dinner 구조체는 Encodable과 Decodable을 모두 동시에 채택한 형태가 되는 것이다! 그렇기 때문에 Dinner을 채택한 인스턴스는 자기 자신을 변환하거나 외부 표현으로 변할 수 있는 타입이 되는 것이다!
<추가> Documentation에서는 Codable을 채택하는 다양한 방법을 소개하고 있다.

Encoding

그럼 이제 이제 Encoding을 하는 간단한 예제들을 살펴보자
// encoder선언! let encoder = JSONEncoder() // Dinner구조체의 인스턴스 생성 let today = Dinner(menu: "치킨", price: 20000) // encoder를 통해 Data형태로 변환 let jsonData = try? encoder.encode(today) // Data형식의 jsonData를 String으로 편환 if let jsonData = jsonData, let jsonString = String(data: jsonData, encoding: .utf8) { print(jsonString) }
Swift
복사
출력 결과를 보면 아래와 같이 나온다!
조금 더 이쁘게 출력을 하려면 아래 코드를 추가하면 된다!
encoder.outputFormatting = .prettyPrinted
Swift
복사

Decoding

Decoding을 하는 방법은 Encoding을 했던 것과 거의 비슷하다!
Encoding 대신 Decoding을 하면 된다!
// decoder 생성 let decoder = JSONDecoder() // jsonString을 data타입으로 변형 var data = jsonString?.data(using: .utf8) // data로부터 인스턴스를 만듬 if let data = data, let today = try? decoder.decode(Dinner.self, from: data) { print(today.manu) }
Swift
복사

Reference