티스토리 뷰

iOS

[iOS] Codable

묵지수 2019. 8. 22. 17:17
이 글은 개인적으로 공부한 내용을 정리한 글입니다. 개인마다 이해한 내용에는 차이가 있을 수도 있으니 감안해주시기 바랍니다.
오타나 내용적으로 부족한 부분에 대한 말씀은 감사하게 받겠습니다!

 

많은 프로그램들은 Server에게 데이터를 보내거나 받기도하고 앱 내부에 데이터를 저장하거나 읽어오는 작업을 수행하고 있습니다.

이 과정에서 데이터의 형태나 형식을 표준화, 보안, 처리 속도 향상, 저장 공간 절약 같은 이유로 다른 형태나 형식으로 변환하는 과정이 발생합니다.

예를들어, json과 object간의 상관관계를 생각하시면 됩니다.

 

이러한 작업을 Encoding, Decoding이라고 합니다.

Encoding은 컴퓨터가 이해할 수 있는 데이터로 변환하는 작업이고,

Decoding은 사람이 이해할 수 있는 언어로 변환하는 작업입니다.

 

많은 프로그래밍 언어에서 Encoding, Decoding을 편하게 해주는 기능을 제공하고 있고 Swift에서도 Codable이라는 기능을 제공하고 있습니다.

 

이 글에서는 Codable에 대해서 알아보고 Encoding, Decoding 과정에 대해서 알아보겠습니다.

 


Codable

우선, Apple 개발자 문서를 보면 Codable에 대해서 다음과 같이 설명하고 있습니다.

 

출처: https://developer.apple.com/documentation/swift/codable

Decodable과 Encodable 두 프로토콜을 모두 채택하는 하나의 타입이라는 것을 알 수 있습니다.

 

여기서 typealias는 기존의 타입에 별칭을 부여해서 코드의 가독성을 높여주도록 해주는 문법입니다.

Int, String, Float같은 Primitive type이나 Class, Struct, Enum 유형에 사용가능하며 Closure도 사용가능합니다.

또한, Codable처럼 두 type을 모두 연관지어서 사용하는 것 또한 가능합니다!

// typealias에 Closure를 사용한 예
typealias CompletionHandler = (Bool) -> ()

 

그러면 이제 Decodable과 Encodable은 무엇인지 알아보면 다음과 같습니다.

 

protocol 타입인 것을 보니 Struct나 Class에서 채택되어 해당 인스턴스가 Encoding되거나 해당 인스턴스로 Decoding될 수 있도록 해주는 것을 알 수 있습니다.

 

즉, Swift의 인스턴스를 다른 데이터 형식으로 변환하기 위해서는 Endodable을, 데이터를 인스턴스로 변환하기 위해서는 Decodable을 채택해야 합니다.

 

name과 age를 프로퍼티로 가지는 People Struct를 예를 들어 보겠습니다.

 

 

 

이제 People Struct는 Codable을 채택하였기 때문에 Encoding과 Decoding을 수행할 수 있습니다.

 

변환되어야 하는 데이터의 Key값과 인스턴스의 프로퍼티 이름이 다른 경우가 있을 수 있습니다.

예를들어, Server에서 건내주는 json에 people_name Key가 존재하지만 인스턴스는 name으로 표현하고 싶은 경우가 있을 수 있습니다.

이러한 상황에서 CodingKey protocol을 이용하면 해결할 수 있습니다.

코드를 보면서 알아보겠습니다.

 

코드를 설명해보자면,

1. Struct 내부에 String 타입의 원시값을 갖는 CodingKeys라는 이름의 Enum을 선언하고 CodingKey 프로토콜을 채택합니다.

2. CodingKeys Enum의 케이스 이름은 Struct의 프로퍼티 이름과 일치해야 합니다.

3. 그리고 프로퍼티의 열거형 case의 값으로 매칭할 json 타입의 Key를 할당하면 됩니다.

4. 만약, json 타입의 Key와 프로퍼티 이름이 일치한다면 값을 할당하지 않아도 됩니다.

 

음... 그러니깐 저 나름대로 CodingKey를 이용한 내부적인 동작을 생각해보면

내부에 CodingKeys Enum이 선언되어 있다면 Encoding, Decoding과정을 거칠 때 CodingKeys Enum에 선언되어 있는 case들의 raw값을 Key값으로 지정한다고 이해했습니다.

CodingKeys Enum이 raw 값으로 String을 가지고 있기에 case에 값을 할당하지 않으면 해당 case가 암묵적으로 프로퍼티의 변수명과 동일한 raw값을 가지기에 Key와 프로퍼티 이름이 일치한다면 값을 할당하지 않아도 되는 것이고요.

 

제가 이해한 것이 틀렸다면 지적부탁드립니다!ㅎㅎ

 

그러면 Encoding, Decoding이 어떻게 진행되는지 알아 보겠습니다.

 


 

Swift 인스턴스와 데이터간의 변환을 위해서는 Decoder와 Encoder가 필요합니다.

Swift에서는 다양한 Decoder와 Encoder를 제공하고 있습니다.(JSONEncoder, PropertyListEncoder, JSONDecoder, PropertyListDecoder...)

이 글에서는 JSONEncoder와 JSONDecoder를 이용하여 json데이터 형식과 Swift 인스턴스 간의 변환을 알아보겠습니다.

Encoding

 

Endoding 과정을 코드로 보면 다음과 같다.

 

 

 

1. Endoding가능한 people인스턴스를 생성

 

2. JSONEncoder 인스턴스 생성

outputFormatting으로 format속성 설정가능
prettyPrinted: 들여쓰기 이쁘게
outputFormatting = .sortedKeys

 

3. JSONEncoder의 encode메서드로 Encoding

해당 인스턴스가 변환될 수 없는 경우가 있으므로 do-catch문으로 감싸주어 예외처리를 해준다.

 

4. Encoding된 데이터를 String타입으로 변환해서 print문으로 출력해서 제대로 변환되었는지 확인

 

Decoding

Decoding 과정을 코드로 보면 다음과 같다.

 

 

 

1. Decoding하고 싶은 데이터를 받아옴. 코드에서는 String으로 json타입 데이터를 작성하고 Decoding가능한 data로 변환.

이때, data는 앱 내부에 존재하는 json이거나 server로부터 응답받은 data일 수 있음

 

2. JSONDecoder 인스턴스 생성

 

3. JSONDecoder의 decode메서드로 Decoding

해당 data가 변환될 수 없는 경우가 있으므로 do-catch문으로 감싸주어 예외처리를 해준다.

 

4. Decoding된 데이터가 Swift 인스턴스로 제대로 Decoding되었는지 인스턴스의 프로퍼티를 읽어서 확인

 


 

Server와 네트워크 통신을 위해서 이러한 변환 작업은 필수적이라고 할 수 있습니다.

이 글에서 다룬 Codable외에도 데이터와 Swift인스턴스간의 손쉬운 변환을 위한 많은 라이브러리가 존재합니다.

어떤 것을 사용하든 개인의 자유지만 무엇을 위해 사용하는지 알고 사용할 필요가 있다고 생각합니다!

 


참고사이트

https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types

https://ko.wikipedia.org/wiki/부호화

'iOS' 카테고리의 다른 글

[iOS] Delegation Pattern  (0) 2019.08.13
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함