앱 샌드박스(App Sandbox)와 Container Directory개념에 대해 알아 보겠습니다.
Sandbox
샌드박스(Sandbox)란 미국에서 어린아이를 보호하기 위해 모래통(Sandbox)에서만 놀도록 하는데서 유래한 보안 모델을 말합니다. 즉, iOS는 기본적으로 앱 마다 별도의 파일을 생성하여 공유되지 않도록 하고 외부로부터 들어온 접근에 대해 보호되는 영역으로 시스템이 부정적으로 조작되는것을 막는 보안 형태입니다.
샌드박스가 있고 없고의 차이
샌드 박스가 아닌 앱은 해당 앱을 실행하는 사용자의 모든 권한을 가지며 사용자가 액세스 할 수있는 모든 리소스에 액세스 할 수 있습니다.
이렇게 모든 앱에 접근할 수 있게 되면 많은 기능들을 할 수 있고 자유롭지만 해당 앱이나 연결된 모든 프레임 워크에 보안 허점이있는 경우 공격자는 해당 앱을 제어하기 위해 해당 취약점을 악용 할 수 있으며 이를 통해 공격자는 사용자가 수행 할 수있는 모든 작업을 수행 할 수 있습니다.
이런 보안 문제 때문에 iOS의 정책은 사용자 앱에 모든 리소스들이나 사용자 데이터에 접근이 가능 불가능합니다.
iOS App Sandboxes
iOS는 위의 그림과 같이 보안상의 이유로 앱 하나당 전부 SandBox화 되어있습니다.
Sandbox는 파일, 환경설정, 네트워크 리소스, 하드뒈어 등에 대한 앱의 접근을 제한하는 세분화된 제어 집합이라고 볼 수 있습니다.
이렇게 되어 있기 때문에, 데이터를 분리하여 고립시키고, 보안 침해의 가능성을 낮춰줄 수 있는 것이죠.
Container
위 그림이 App의 Sandbox 디렉토리를 보여주는 그림입니다.
보안을 위해 iOS 앱과 파일 시스템의 상호 작용은 앱의 sandbox 디렉토리에있는 디렉토리로 제한됩니다.
새 응용 프로그램을 설치하는 동안 설치 프로그램은 sandbox 디렉토리 내에 응용 프로그램용 컨테이너 디렉토리를 만듭니다. 각 컨테이너 디렉토리에는 특정 역할이 있습니다.
Bundle 컨테이너 디렉토리는 앱의 Bundle을 보유하고 Data 컨테이너 디렉토리는 앱과 사용자 모두에 대한 데이터를 보유합니다. 이 디렉토리는 앱이 데이터를 정렬하고 구성하는데 사용할 수 있는 여러 하위 디렉토리로 더 나뉩니다. 앱은 런타임에 추가 컨테이너 디렉토리(예 : iCloud 컨테이너)에 대한 접근을 요청할 수도 있습니다.
Bundle Container
Bundle 경로
Bundle.main.bundlePath
Bundle의 특징
- Bundle Container는 파일 시스탬 내 하나의 디렉토리입니다.
- 실행 가능(Executable)파일, info.plist, Resources(이미지, 사운드, strings 등)등을 함께 그룹화 합니다.
- 읽기 전용, 수정이 필요한 경우 데이터 컨테이너로 옮겨서 작업합니다.
- iTunes, iCloud에 백업되지 않습니다.
Bundle 디렉토리 내부 파악
-
패키지 내용 보기
- Compile Sources들이 바이너리 형태의 실행파일로 변하게 된다.
- 라이브러리는 프레임워크에 들어가게 된다.
- Storyboard, xib, strings 파일들이 들어가게된다.
- Assets에 들어있는 Resource들이 들어가게 된다.
Data Container
- Data Container 구조
Data Container 경로
NSHomeDirectory()
Data Container 특징
- 기본 디렉토리 - Document, Library, tmp, SystemData
- 사용자가 직접 디렉토리나 파일을 추가할 수 없으며, Documents같은 서브디렉토리를 통해 관리.
1.Documents 폴더
NSHomeDirectory() + "/Documents"
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
- 유저가 앱을 통해 생성한 문서나 데이터, 또는 외부 앱을 통해서 전송한 음악, pdf등의 컨텐츠를 저장
- 설정에 따라 유저가 직접 파일 추가 및 삭제 가능. (plist에서 UIFileSharingEnabled를 YES로 했을 경우) 따라서 유저에 의해 삭제되거나 내용이 변경되어도 무방하고 유저가 다루는 컨텐츠와 관련이 있는 파일들만 저장
- Documents 디렉토리 자체는 삭제 불가
- Documents 디렉토리 삭제 시도 시 Documents 내의 디렉토리, 파일들만 일괄 삭제
- iTunes, iCloud에 백업된다.
UIFileSharingEnabled
설정을 해주면 iCloud에서 도큐멘트에 접근이가능하고, 파일추가나 삭제가 가능하다.
2. Documents/Inbox 폴더
NSHomeDirectory() + “/Documents” + “/Inbox”
- 타 앱을 통해 전송받은 파일이 저장되는 디렉토리 e.g) 메일 앱 첨부파일 공유 등
- 파일들을 읽거나 삭제할 수는 있지만, 새 파일을 추가하거나 기존 파일 수정 불가
- 타 앱에서 동일 이름 파일 전달 시 덮어쓰기 대신 [file-1.txt, file-2.txt]처럼 번호가 자동으로 부여되서 새 파일 생성.
- iOS 9.0부터 디렉토리가 한 번 만들어진 이후로는 삭제 불가하며 파일만 삭제가능.
- 유저가 직접 생성 불가능
- Documents와 동일하게 디렉토리 삭제 시도 시 Inbox내의 파일들만 일괄 삭제
CFBundleDocumentTypes
3. tmp/[BundleID]-Inbox 폴더
NSTemporaryDirectory() + Bundle.main.bundleIdentifier! + “-Inbox”
- LSSupportsOpeningDocumentsInPlace키의 값이 NO일때 iCloud드라이브 관련 / Files앱 / DocumentsPicker등에서 공유되는 파일들이 저장되는 디렉토리
- Documents/Inbox와 달리 디렉토리 및 파일을 다루는 제약 없음.
- tmp 디렉토리에 속성을 따르므로 백업되지 않으며 시스템에 의해 삭제될 수 있음.
LSSupportsOpeningDocumentsInPlace
- NO - 원본 파일에 대한 사본을 Inbox 디렉토리에 생성
- YES - 원본 파일 url을 그대로 사용. File Coordinator, File Presenter등을 통한 관리 필요
4. Library 폴더
NSHomeDirectory() + "/Library"
FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask)[0]
NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true)[0]
- 유저 데이터 파일 및 임시 파일을 제외한 모든 파일들을 관리
- 유저에게 노출되는 것을 피하고 앱의 기능이나 관리에 필요한 파일 저장
- 주로 서브디렉토리인 Application Support와 Caches를 이용하지만 커스텀 디렉토리 사용 가능
- Preference, Cookies, Saved Application State, WebKit등 필요할 때 시스템에서 자동 생성.
- iTunes, iCloud에 백업
5. Library/Application Support 폴더
FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0]
NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true)[0]
- 앱의 기능 또는 관리를 위해 지속적으로 관리해야 되는 파일 저장
- Documents와 거의 동일한 속성을 지니며, 유저에 대한 노출 여부에 따라 위치 결정( Document와 달리 노출이 되지 않는다.)
- BundleID나 회사명 등의 서브디렉토리를 만들어 관리
- CoreData 기본 저장 경로
- iTunes, iCloud에 백업된다.
CoreData vs Realm
CoreData는 기본적으로 Library/Application Support폴더가 기본경로기 때문에 노출이 되지 않지만,
Realm은 파일이 기본적으로 Documents경로를 사용하는데 Documents폴더는 노출되기 때문에 중요한 정보들이 저장되어있다면 Application Support폴더로 변경해서 사용하는것이 좋다.
6. Library/Caches 폴더
FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0]
- 앱의 동작 속도 / 데이터 절약 등을 위해 사용하는 공간
- 필요하면 쉽게 재생성하고 다운로드 받을 수 있는 파일이어야 한다. e.g) 지도 정보, json파일 등
- 디스크 공간이 부족하거나 시스템 복원, 앱 데이터 등의 경우에 시스템이 자동으로 파일 삭제할 수도 있다.
- 어느 순간 삭제되어도 앱의 동작에는 영향이 없을 파일만 저장.
- 백업되지 않음.
7. Library/Caches/Snapshots 폴더
- applicationDidEnterBackground(_:)메서드 호출 후 현재 뷰에 대한 스냅샷 생성되어진다.
- Background에서 Foreground로 넘어올 때 LaunchScreen을 사용했던것이 아니라 applicationDidEnterBackground(_:)메서드 호출 후에 저장됬던 스냅샷 이미지를 사용했던 것!
- Restore Application State 기능 사용 시, Suspend상태에서 종료되었던 앱이 재 실행될때 사용자에게 앱이 종료되지 않고 계속 실행되고 있었던 느낌을 주기 위해 SnapShot 이미지를 사용한다!
Restore Application State
쉽게 만약 앱에서 2번째 탭바에서 내용을 보고 있다가 다른 앱으로 넘어가거나 종료했으면 2번째 탭바에 있었다는것을 기억하는것과 같이 앱의 상태를 기억하고있는것!
8. Library/Preferences 폴더
NSHomeDirectory() + “/Library” + “/Preferences”
- 앱의 설정 정보 저장
- 별도의 파일을 저장할 수는 있지만 직접 조작하지 않는것을 권장.
- 대신 UserDefaults, Settings.bundle, CFPreferences API등을 이용할 것.
- iTunes, iCloud에 백업.
9. tmp(Temporary)
NSTemporaryDirectory()
- 현재 앱 실행 중에 사용하지만 다음 앱 런칭시까지 유지할 필요 없는 임시 파일 저장 공간
- 시스템이 주기적으로 파일을 삭제하더라도, 사용 후 필요없어진 파일은 직접 삭제해주는 것을 권장
- 앱이 실행되고 있는 동안에는 삭제 되지 않음.
- 백업 되지 않는다.
이미지 캐싱 라이브러리인 SDWebImage라이브러리를 보면 폴더의 사용 형태를 알 수 있습니다.
- queryDiskCacheForKey() 메서드를 이용해서 저장되있는 Cache를 찾는다
- Library/Caches폴더에 캐쉬된 이미지가 없으면 downloadImage(url, options, progress, completed)메서드를 이용해 다운을 받고 tmp폴더에 잠시 저장했다가(앱 시작중에는 데이터 유지가 필요하지 않기 때문에), Library/Caches폴더에 저장하는 형태입니다.
요약
- 컴파일때 파일 생성여부
- Bundle Container (O)
- Data Container (X)
- 유저 접근 가능 여부
- Documents (O)
- Application Support (X)
- 지속성 및 백업 여부
- Documents, Library (O)
- Library/Caches, tmp (X)
- 앱 실행 중에 데이터 유지 필요 여부
- Library/Caches (O)
- tmp (X)
'iOS' 카테고리의 다른 글
[iOS] NotificationCenter (0) | 2019.07.24 |
---|---|
[iOS] UIDocumentInteractionController (1) | 2019.07.24 |
[iOS] 오토레이아웃(AutoLayout)과 Layout 개념 (0) | 2019.07.23 |
[iOS] 델리게이트(Delegate) (0) | 2019.07.23 |
[iOS] UserDefaults (0) | 2019.07.23 |