카테고리 없음

key Archiving in swift (아카이브 ,언아카이브)

jin_j_i_n 2021. 9. 14. 02:25

Key Archive에 대해서 알아보는 포스팅이다.

일단 필자는 Archive라는 단어 자체랑 서먹함을 느끼기 때문에 아카이브의 뜻을 짚고 넘어가겠다

보관소!

보관소 라는 의미를 가진단다. 어떤 것을 보관한다거나 보관하는곳을 의미할때 쓰이는 단어로 추측이 된다.

그러면 스위프트에서 Archive라는 행위가 있을텐데 (그래서 이 포스팅을 쓰는것...) 어떤 클래스나 객체로 구현되어있을까? 

 

공식문서의 Archive에 대한 설명을 살펴보자

 Archives provide a detailed record of a collection of interrelated objects and values

(아카이브는 상호 관련된 개체 및 값 모음에 대한 자세한 기록을 제공합니다.)

-> 어떠한 객체에 관련된 자세한 값들을 저장한다는 의미인것 같다.

 

그래서 archiving in swift 라는 키워드로 검색했는데,,, 애플 공식문서에 바로 뜨는 객체는 바로

NSKeyedArchiver  이라고 나와있는데, 공식문서의 설명을 해석해보면 키에 의해 참조되는 아카이브 하기 위한 객체들의 데이터를 저장하는 인코더  정도로 해석할 수 있겠다.

 

좀 정리해보자면 인코더인데 key에 의해 관리되고, 아카이브 하려는 객체들을 저장하는 인코더를 의미하는것 같다.

 

또한 NSKeyedArchiver 에 의해 아카이브 되어서 저장된 객체를 언아카이브 하기 위해서는 NSKeyedUnArchiver 라는 디코더를 사용한다.

 

단순하게 이야기하자면  인코딩해서 객체를 저장하고 (아카이브하고), 디코딩을 하려면 NSKeyedUnArchiver 라는 디코더를 쓴다는것 같다. (그래서 NSCoder를 상속받는다)

 

근데 객체를 저장하면 그냥 저장 (Userdefault와 같은...) 하면 되지 왜 인코딩하고 디코딩하고 귀찮은 과정을 거쳐서 하는걸까?? 🤔

.

..

😮!!

이글을 쓰면서 알게 된 사실인데 방금 언급한 Userdefault 조차도 데이터를 저장할때 Archive 와 Unarchive 과정을 통해 저장이 이루어진다. 이 과정을 위해선 저장하려는 타입은 NSObject를 상속받고 , NSCoder 프로토콜을 준수해야한다.

 

그렇다면 iOS에서 어떠한 데이터를 저장하려면 NSCoder 프로토콜을 준수하고 아카이브, 언아카이브 과정을 통한다는건데, 아직은 잘 이해가 안가고 모호할 수 있으니 마지막으로 NSCoder만 알아보고 가자

 

NSCoder

(공식문서)

NSCoder declares an extensive interface for taking the information stored in an object and putting it into another format suitable for writing to a file, transmitting between processes or across a network, or performing other types of data exchange

( NSCoder는 객체에 저장된 정보를 가져 와서 파일에 쓰기, 프로세스 간 또는 네트워크를 통해 전송 또는 다른 유형의 데이터 교환 수행에 적합한 다른 형식으로 만들기 위한 광범위한 인터페이스를 선언합니다. )

 

..오호 NSCoder라는 타입을 사용하면 파일에 저장하거나, 프로세스, 네트워크 간의 통신이 용이한 인터페이스를 제공할 수 있다는 것이다.

여기서 위에 정리한 것을 붙여보면, NSCoding 프로토콜을 따르는 객체만이 아카이브가 될 수 있다는것이다. (NSCoding? NSCoder? 무슨차인지는 모르겠지만 일단 비슷한 맥락으로 받아들이겠다)

 

찐으로 정리하자면 Keyed Archiving은 NSCoding의 프로토콜을 준수하고 NSObject를 상속받는 객체와, 해당 객체와 관련된 모든 값들을 저장할때 쓰이는 방식이라 할 수 있겠다, 그과정에서 인코딩하기 위해 NSKeyedArchiver 를 쓴다는것이고!

 

자 이제 어느정도 정리가 된 것 같으니 그럼 마지막으로 Keyed Archiving 하는 방법을 알아보고 포스팅을 마무리하겠다.

 

위에서부터 입아프게 (사실은 손아프게) 아카이빙을 하려면 NSCoding 프로토콜을 준수하는 객체여야 한다. 

저장하려는 데이터를 NSCoding 프로토콜을 준수하는 클래스로 만들어 보자

 

 

 

간단한 변수들을 선언하려했는데 빨간줄이 뜬다. NSCoding 프로토콜을 준수하려면 필수로 선언해줘야하는 부분들이 있는것 같다. 일단 Fix 를 눌러보자

첫번째 함수는 왠지 처음보는것 같고

두번째 함수는 어디서 본것 같은데... 찾아보자

 

1. encide(with:)

주어진 아카이버를 활용하여 압축을 진행하는 객체의 프로퍼티들을 압축한다.

2. init?(coder: NSCoder)

아카이브( 저장된 데이터 )를 읽을때 사용된다. Unarchiver를 통해 언아카이브된 데이터를 초기화 해주는 함수이다.

 

그렇다면 1번은 아카이브 해주는 과정이고,,, 2번은 언아카이브된 데이터를 가지고 객체를 초기화 해주는 과정이라 생각하면 되겠다.

당연히 압축을 통해 저장하니 압축을 푸는 과정도 필요하기 때문이다.

그렇다면 1번, 2번 함수를 선언해주도록 해보자.

 

디폴트값은 없앴다

자 이제 아무런 에러도 안뜨고 NSCoding 프로토콜을 사용하여 인코딩, 디코딩 될 수 있는 객체를 만들었다.

이제 아카이브를 하여 한번 아카이빙 된 데이터를 얻어보자.

 

먼저 NSKeyedArchiver를 사용해 데이터를 아카이브 해준다, 이때 아카이브된 데이터는 Data 타입이다.

아카이브된 data를 언아카이브 해주고, 언아카이브된 데이터를 출력하여 아카이빙되기전의 데이터 프로퍼티랑 일치한지 확인해보자.

 

성공적으로 언아카이브되고, 프로퍼티값들도 일치함을 볼 수 있다

참고로 이러한 방식을 통해 클래스의 깊은 복사를 구현할 수 있다.

오늘 포스팅 끝!

 

 

참고 : https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Archiving/Articles/archives.html#//apple_ref/doc/uid/20000946-BAJDBJAI