오늘은 프린트와 관련하여 파일을 많이 다루는 프로젝트를 하다보니 눈길과 손길이 많이 갔던 FileManager
와 UIDocumentPickerViewController
에 대해 좀 더 학습하면서 정리하는 시간을 가지고자 한다.
iOS에서 파일 시스템은 SandBox 구조로 되어있다. 마치 아이들이 모래사장 안에서만 놀다가 나올 때는 흙을 다 털고 깨끗하게 나올 수 있는 것처럼 앱을 중심으로 내외부를 적절하게 분리시켜 보호받을 수 있도록 고안된 형태이다.
방음이 잘 되는 코인노래방처럼 앱마다 고유의 영역을 부여하고 외부로부터의 간섭이나 외부로의 접근을 적절하게 제어할 수 있는 형태. 샌드박스 형태가 아니라면 하나의 앱으로부터의 영향이 다른 앱과 시스템에까지 연쇄적으로 작용할 수도 있다.
카카오톡에서 데이터를 다운받았을 때, 다운받은 데이터의 상세 화면으로 들어가서 공유 버튼 같은 걸 누르고 파일에 저장 같은 액션을 취하지 않으면 내 폰에서 다운받은 데이터를 파일 앱을 통해 확인이 불가한 것을 경험해본 적 있을 것이다.
즉, 해당 데이터는 앱 내부의 디렉토리에 저장된 터라 별다른 액션 없이는 외부에서 접근할 수 없는, 이러한 샌드박스 구조의 아주 훌륭하지만 꽤나 귀찮은 점을 대다수 몸소 경험해본 바가 있다.
위의 그림과 같이 하나의 앱에서 상호작용할 수 있는 파일은 SandBox
디렉토리 아래의 디렉토리로 제한된다. 각각의 컨테이너 디렉토리는 특정 역할을 수행하는데 Bundle Container
는 해당 앱의 번들을 보유하고 Data Container
는 앱과 사용자 모두에 대한 데이터를 보유한다.
그렇기에 Data Container
는 데이터의 특성에 맞춰 정렬하고 사용할 수 있도록 자신의 하위에 여러 디렉토리를 구성하고 있다. 추가적으로 앱은 런타임 중에 iCloud Container
와 같이 타 컨테이너 디렉토리에 대한 접근을 요청 가능하다.
앞서 설명한 SandBox Directory
내부에 있는 하위 디렉토리는 각각 아래와 같은 역할을 한다.
1. AppName.app (Bundle Container)
: 앱의 번들로서 앱과 모든 리소스를 포함한다. 따라서 앱 설치 시에 번들 디렉토리는 변조 방지를 위해 서명이 되는데 해당 디렉토리에 '쓰기' 작업이 가능하게 되면 서명이 변경되며 앱의 실행이 불가하게 되다보니 '쓰기' 작업을 할 수 없게 되어 있다. 다만 '읽기' 전용으로 접근 권한을 얻을 수는 있다.
해당 디렉토리의 내용은 iTunes나 iCloud에 의해 백업되지 않는다.
2. Data Container
Documents/
: 사용자가 생성한 데이터를 저장하는 공간으로 파일 공유를 통해 사용자가 직접 사용할 수도 있다. iTunes나 iCloud에 의해 백업되므로 공개가 되어도 괜찮은 데이터만 포함되어야 한다.
Documents/Inbox
: 외부의 앱으로부터 요청하여 가져온 데이터를 저장하며, '읽기'나 '삭제'는 가능하지만 '쓰기' 작업은 불가하다. 편집을 원할 경우에는 디렉토리 바깥으로 이동해주어야 한다.
iTunes나 iCloud에 의해 백업된다.
Library/
: 모든 데이터 파일의 최상위 디렉토리로서 사용자에게 직접 노출되지 않는다. 일반적으로는 Application Support
와 Caches
등의 하위 디렉토리를 사용하지만 사용자가 하위 디렉토리를 직접 생성할 수도 있다.
Caches
디렉토리를 제외한 나머지는 iTunes나 iCloud에 의해 백업된다. 사용자가 생성한 데이터 파일을 보관하기 위한 용도가 아닌 앱 실행에 필요한 데이터들을 위한 용도로 사용해야 한다.
Application Support
에는 주로 구성 파일이나 템플릿 등 사용자에게 노출되지 않으면서 앱에 필요한 파일들을Caches
에는tmp
의 데이터보다는 오래 유지되어야 할 필요가 있는 데이터를 캐시
tmp/
: 재사용이나 앱 실행 시에 필요하지 않는 데이터를 임시로 저장해주는 용도로서 iTunes나 iCloud에 의해 백업되지 않고 시스템이 주기적으로 정리해준다.
3. iCloud Container
: iCloud를 사용하는 앱의 파일을 저장하기 위한 시스템을 제공하기 위한 컨테이너 디렉토리이다. 각 컨테이너 디렉토리 내부는 Documents
와 Data
파일로 분리되어 있으며, Documents
의 하위 디렉토리 내에 있는 모든 파일이나 패키지 등은 개별적으로 삭제할 수 있는 별도의 문서로 사용자에게 전달된다.
즉, 사용자가 직접 보거나 수정할 수 있는 데이터 외에는 모두 Documents
디렉토리 외부에 배치해야 한다.
(iCloud Container
를 사용하기 위해서는 추가적인 설정들이 필요하다.)
기본적으로 백업이 되는 디렉토리는
NSURLIsExcludedFromBackupKey
를 통해 파일을 백업에서 제외할 수 있다. 용량이 너무 큰 데이터의 경우에는 이렇게 백업을 제외시켜주는 것이 좋다.
이처럼 사용자가 직접 접근하기 어려운 샌드박스 형태의 파일 시스템에 접근하여 데이터를 관리하기 용이하도록 만든 클래스이다. 파일 시스템과 상호 작용하는 것이 주 기능으로서 파일이나 디렉토리를 찾거나 생성하고, 복사 및 이동 등의 다양한 액션을 수행할 뿐더러 정보나 속성을 가져오거나 변경할 때도 활용할 수 있다.
대표적인 FileManager의 기능
- 현재 디렉토리 경로값 확인
- 디렉토리의 생성/변경/삭제
- 파일 존재 여부 확인
- 파일 생성/읽기/쓰기/삭제/복사/옮기기
본격적인 사용법은 다음 포스트에서 작성해보고자 한다. 다만 끝마치기 전에 FileManager
로 생성한 파일을 아이폰에서 사용자가 '파일' 앱을 통해 실제로 확인할 수 있도록 하기 위해서는 Info.plist
에서 설정해줘야 하는 부분이 있다.
총 두 가지 방법으로 설정이 가능하다.
1) Supports Document Browser
설정
Supports Document Browser
키 값을 추가하고 값을 YES로 설정하는 방법이다. 이러면 '파일' 앱에서 해당 앱의 이름으로 생성된 디렉토리가 보이며 저장된 파일에 접근도 가능하다.
다만 공식 문서에 따르면 해당 앱이 문서 기반 앱인지 여부를 나타내는 부울 값이라고 설명되어 있어, 문서 기반 앱이 아닌데 단순히 파일을 탐색 가능하게 하려고 해당 설정을 YES로 두어도 되는가에 대해서는 고민이 필요해 보인다.
2) Supports opening documents in place
설정
Supports opening documents in place
키 값을 추가하고 값을 YES로 설정하는 방법이다. 다른 앱에서 문서의 복사본이 아닌 원본 문서를 열 수 있는지를 알려주는 설정이며, 아쉽게도 위의 Supports Document Browser
와 달리 해당 키만 추가해서는 파일을 탐색할 수가 없다. Application supports iTunes file sharing
의 값을 YES로 설정하여 해당 파일이 공유될 수 있도록 해주어야 한다.
전반적인 파일 시스템과 파일 매니저에 대한 내용을 정리해보았다. 이것저것 시도해보면서 개념을 파악해보려다보니 막혔었던 부분을 해결하는 쾌거를 얻기도 하였다. 다만 그리 쉽지 않은 내용이다보니 정리하면서도 개념에 대한 확신을 갖기 어려웠다.
특히 마지막에 정리한 Info.plist
와 관련된 내용은 직접 이것저것 실행해보면서 알게된 내용이기는 하지만 그래서 저 두 방법 간의 차이나 왜 꼭 저것들을 써야되는지에 대한 깊은 이해는 아직까지도 부족하다고 느껴진다. 일단은 계속해서 찾아보겠지만, 혹시 이 의문에 대한 명확한 답을 알고 있는 분이 계신다면 살포시 댓글을 남겨주시면 좋을 듯 하다.