iOS 파일 시스템

Android와 다르게 iOS는 그 내부가 잘 보이지 않는 듯하다. 예전 iPod touch를 쓸 때도 문서를 iPod touch에 보관해 마치 저장 장치처럼 쓰려고 했지만 특수한 소프트웨어를 써야지만 할 수 있었던 기억이 난다. 지금은 그것이 애플이 보안을 위해서 그렇게 한다고 알고 있지만 굉장히 아쉬웠던 기억이었다.

iOS를 공부하면서 내부의 폴더명이 가끔 나오는데 정확히 어떤 역할을 하는지 궁금했고 최근 let us: Go! 2018 Spring에서 giftbot 님의 세션을 복습할 겸 공부하려 한다.

APFS(Apple File System)

iOS 파일 시스템 전에 애플의 현재 파일 시스템인 APFS에 대해 조사해 보았다.

먼저 파일 시스템(File System)이란 컴퓨터에서 파일이나 자료를 쉽게 발견 및 접근할 수 있도록 보관 또는 조직하는 체제를 가리키는 말이다. 보통 보조 기억 장치에 파일들을 보관하는 데 이 파일들을 효율적으로 관리하고 저장 및 접근하기 위한 일련의 체계를 일컫는다.

애플의 최신 파일 시스템인 APFS는 그 중 파일 시스템의 다양한 종류 중 디스크 파일 시스템 에 분류되며 이는 디스크 드라이브를 다룬다. 애플은 2016년 APFS가 나오기 전까지 HFS+ 라는 파일 시스템을 사용하고 있었다. 그러나 최근의 환경에 맞춰 APFS로 교체하게 된다. 개선점을 몇 가지 적어보면,

  • 하드 디스크에 최적화 => 플래시 메모리에 최적화
  • Copy-On-Write 방식으로 낸드 플래시 기반 저장장치에 가해지는 부담 최소화
  • 암호화를 전반적으로 지원해 보안을 강화

이러한 장점을 가진 APFS를 iOS 10.3부터 기본 파일 시스템으로 채택했다.

About the iOS File System

iOS 파일 시스템은 동작하는 그 앱에 맞춰져 있다. iOS에서는 시스템의 간결성을 위해 기기의 유저가 바로 파일 시스템에 접근하지 못하고 앱들은 이 규칙에 따르도록 한다.

iOS Standard Directories

iOS의 앱은 보안을 이유로 그 앱의 SandBox(샌드박스) 디렉토리 안에서 파일 시스템과 상호 작용할 수 있도록 제한한다. 설치 시, 인스톨러는 각각의 역할을 가진 컨테이너 디렉토리들을 샌드박스 디렉토리 안에 설치한다.

  • Bundle Container — 앱의 번들을 담는다.
  • Data Container — 앱과 유저의 데이터를 담는다. 이 데이터 컨테이너는 다시 서브 디렉토리로 나뉘어져 많은 데이터들을 나눠 관리한다.
  • iCloud Container — 실행 시에 iCloud와 관련된 것을 담는다.

앱은 보통 컨테이너 디렉토리 바깥을 접근하고 파일을 만드는 것이 금지되어 있다. 특별히 유저의 전화부나 음악 같은 시스템 인터페이스를 이용할 때는 시스템 프레임워크가 원하는 동작을 수행할 수 있게 도와준다.

다음은 iOS 앱에서 자주 쓰는 디렉토리들이다.

AppName.app

앱의 Bundle(번들)파일이다. 이 디렉토리에 쓸 수 없으며 읽기만 가능하다. 변조를 막기 위해 설치 시 CodeSignature 를 넣는다. 이 디렉토리는 iTunes나 iCloud에 백업되지 않는다.

여기서 번들이란 실행 코드와 이미지, 사운드 같은 리소스들을 한데 묶은 디렉토리이다. 번들은 어플리케이션이나 다른 소프트웨어를 설치하거나 이동시킬 때 편리하다. 또 로컬라이징 파일을 번들의 서브 디렉토리로 넣음으로써 유저의 언어 설정에 따라 자동적으로 변환된다. 번들은 Xcode가 자동으로 만들어 준다.

Documents

Data Container의 서브 디렉토리로 유저가 앱을 통해 생성한 문서나 데이터, 또는 외부 앱에서 받은 파일을 저장한다. 유저에게 노출되는 파일만 저장해야 하며 디렉토리의 파일들은 iTunes와 iCloud로 백업이 된다.

이 디렉토리의 파일들은 iTunes을 통해 옮길 수 있는 File Sharing(파일 공유)을 지원하는 데, 이것은 Info.plist의 UIFileSharingEnabled 키를 YES(true)로 하면 사용이 가능하다.

LSSupportsOpeningDocumentsInPlace 키를 YES로 하면 파일의 원본을 열 수 있다. 이 키와 UIFileSharingEnabled 키를 둘 다 YES로 할 경우에는 Documents 디렉토리의 모든 파일에 접근이 가능해 Files 앱에서 확인 및 수정이 가능하다.

Library

유저 데이터가 아닌 파일들이 저장되는 가장 최상단 디렉토리로 Application SupportCaches 서브 디렉토리를 주로 사용한다.

유저에게 노출되고 싶지 않은 파일들을 서브 디렉토리에 저장하면 되며 Caches를 제외한 디렉토리들은 iTunes와 iCloud에 백업이 된다.

Library의 주요한 서브 디렉토리에는 다음과 같은 것들이 있다.

Application Support

사용자의 documents를 제외한 나머지 앱의 데이터 파일들을 저장하는데 사용한다. 앱이 생성하고 관리하는 데이터, 설정, 리소스 등이 저장되며 이 디렉토리의 모든 컨텐트들은 앱의 bundle identifier 나 회사 이름의 서브 디렉토리에 위치한다. iTunes와 iCloud에 백업이 가능하다.

Caches

앱이 쉽게 재생성 할 수 있는 파일, 쉽게 다운로드 받을 수 있는 파일들이 저장된다. 앱의 성능을 위한 목적으로 존재하며 캐시로는 데이터 베이스 파일이나 다운로드 파일 등이 고려된다. 앱이 실행 중에는 삭제되지 않는 것이 보장되며 백업은 되지 않는다. Caches/Snapshots 디렉토리에는 앱이 백그라운드로 넘어갈 때 저장되는 앱의 스냅샷이 저장된다.

Preferences

앱의 중요 설정이 담겨 있는 디렉토리NSUserDefaults 클래스를 사용해 파일을 만들어 저장할 수 있다. 이 유저디폴트 파일은 iTunes와 iCloud에 저장이 된다.

tmp

다음 앱을 실행하는 데 필요가 없는, 말 그대로 임시 파일들을 담는다. 백업은 되지 않으며 시스템은 앱이 실행중이지 않을 때 이 디렉토리를 비운다.

어디에 앱의 파일을 넣어야 할까?

  • 유저 데이터는 Documents 에 저장.
  • 앱 생성 데이터는 Library/Application support 에 저장.
  • 용량이 큰 파일(예: 미디어 파일) 같은 경우 NSURLIsExcludedFromBackupKeyNSURL 인스턴스의 메소드인 setResourceValue(_:forKey:) 에 전달해 백업이 되지 않도록 한다.
  • 임시 파일은 tmp 에 저장.
  • 데이터 캐시 파일은 Library/Caches 에 저장

Reference