iCloud Documents 디자인하기(iOS & OS X 프로그래밍 가이드)

2

iCloud Design Guide 세 번 째 챕터 번역입니다.

공식문서 원본: Designing for Documents in iCloud

 

iCloud 문서 저장소(iCloud document storage)를 사용하면 모든 사용자의 기기에서 앱의 문서를 사용할 수 있다. (iOS의 UIDocument 클래스 또는 OS X의 NSDocument 클래스를 기반으로 한) 문서(document)는 디스크에 단일 파일이나 파일 패키지로 기록할 수있는 관련 데이터의 모음이다. 파일 패키지(file package)는 사용자에게 단일 파일로 제공되는 디렉토리이며 NSFileWrapper 객체를 통해 앱에서 액세스 할 수있게한다.

문서는 iCloud 앱에서 예상되는 대부분의 동작을 자동으로 구현한다. 특히, 문서는 로컬 변경 사항이 iCloud에서 발생한 변경 사항과 안전하게 조정되도록 자동으로 보장해준다. 파일 코디네이터 (NSFileCoordinator) 객체를 채택하고 파일 프리젠터 (NSFilePresenter) 프로토콜을 채택하여 이것을 수행한다. OS X v10.8(마운틴 라이언) 이상에서는 문서가 자동으로 열기 / 저장 / 이름 바꾸기 UI 및 기능을 제공한다. iOS에서 앱에서는 이러한 것을 직접 구현해야한다. iCloud 문서 작업시 파일 코디네이터 및 프리젠터 사용은 필수이다.

 

아이클라우드 문서 저장소가 동작되는 원리

파일 및 디렉토리를 iCloud document storage에 기록하면 시스템은 해당 항목을 iCloud 서버와 사용자의 다른 장치로 자동으로 전송한다. iCloud document storage 사용은 다음 요구 사항을 제외하고는 로컬 파일 시스템 사용과 유사하다:파일 및 디렉토리를 iCloud document storage에 기록하면 시스템은 해당 항목을 iCloud 서버와 사용자의 다른 장치로 자동으로 전송한다. iCloud document storage 사용은 다음 요구 사항을 제외하고는 로컬 파일 시스템 사용과 유사하다:

  • 앱은 Xcode 기능을 사용하여  Request Access to iCloud Using Xcode Capabilities에 설명 된대로 iCloud 컨테이너 디렉토리에 액세스 할 수있는 권한을 요청해야한다.
  • 앱은 iCloud storage APIs를 사용하여 iCloud 컨테이너 디렉토리를 구성 및 액세스하고 파일을 관리해야한다.
  • 아래의 ‘파일과 디렉토리에 접근하기위한 File Coordination 사용‘에 설명 된대로 앱은 file coordination을 사용하여 파일 내용을 읽고 쓸 수 있어야한다.

 

iCloud document storage가 작동하는 방식을 이해하려면 실제로 사용해보는 것이 좋다. 아래의 그림 3-1은 장치의 로컬 저장소를 간략하게 보여준다. 앱의 로컬 데이터 디렉토리 외에도 앱은 적절한 권한(entitlements)이 있는 모든 iCloud 컨테이너에 액세스 할 수 있다. iCloud 컨테이너 자체도 장치에 있지만 파일 시스템의 다른 부분에 있으므로 사용하기 전에 구성해야한다. iCloud 컨테이너를 사용하도록 구성하려면 백그라운드 스레드에서 NSFileManager 의 URLForUbiquityContainerIdentifier: 메서드를 호출하여 (1 단계) 액세스 할 iCloud 컨테이너를 지정한다. 시스템이 컨테이너를 구성하고 (2 단계) 컨테이너 디렉토리의 기본 URL을 반환한다. 당신은 이 기본 URL을 사용하여 파일 및 디렉토리를 지정하는 추가 URL(확장경로)을 작성하고 그 URL을 사용해서 메타데이터 쿼리를 작성하여 iCloud 컨테이너를 검색한다 (3 단계).

그림 3-1  데이터와 iCloud 지원 앱 관리의 상호 작용
그림 3-1  데이터와 iCloud 지원 앱 관리의 상호 작용

참고:일반적으로 각 앱의 iCloud 컨테이너에대해 NSFileManager의 URLForUbiquityContainerIdentifier: 메소드를 명시 적으로 호출한다. OS X 문서 기반 앱의 경우 앱의 NSDocument 객체가 당신을 대신해서 자동으로 이 메소드를 호출한다.

 

파일과 디렉토리에 접근하기위한 File Coordination 사용

컨테이너의 파일과 디렉토리에 접근 할 때 iCloud 앱은 file coordination(파일 코디네이션)을 사용해야한다. file coordination은 데이터 무결성을 유지하기 위해 파일 코디네이터 및 파일 프리젠터 객체를 사용하여 파일 및 디렉토리에 대한 접근을 직렬화(serialize)한다. 파일 프리젠터는 파일을 감시하고 또 다른 스레드 또는 프로세스가 해당파일에 조치를 취할 때마다 알림을받는다. 파일에 대한 모든 작업은 파일 코디네터를 통해 이루어져야한다. 파일 코디네이터는 (파일에) 관여하고 있는 파일 프리젠터와 함께 해당 작업을 조정한다. 예를 들어, 어떤 파일을 한 위치에서 다른 위치로 이동할 때 파일 코디네이터는 이 파일과 이해관계가있는 파일 프리젠터에게 새 위치를 알린다. 그리고 파일에 기록할 때 모든 파일 프리젠터가 안전하다고 할 때까지 파일 코디네이터는 해당 쓰기 작업을 연기한다.

document(문서) 객체 (iOS에서는 UIDocument, OS X에서는 NSDocument)를 사용하는 앱은 파일 코디네이션을 기본으로 갖게된다. 문서 객체는 프리젠터 (NSFilePresenter) 프로토콜을 구현하고 그 프로토콜 메소드를 사용하여 기본 파일 또는 파일 패키지를 관리한다. 파일 내용을 읽거나 쓸 때 문서 객체는 파일 코디네이터 (NSFileCoordinator 클래스의 인스턴스)를 자동으로 사용한다. 문서 객체를 사용하여 파일에 액세스하지 않는 경우 당신은 반드시 파일 코디네이터를 직접 처리해야한다. 당신의 객체에서 파일 코디네이터를 지원하는 방법에 대한 자세한 내용은  File System Programming Guide에서 The Role of File Coordinators and Presenters를 참조할 것.

 

아이클라우드와의 데이터 전송

앱이 처음으로 문서의 디스크상의 데이터표현을 iCloud (ubiquity) 컨테이너에 추가하면 그림 3-2와 같이 시스템이 전체 파일 또는 파일 패키지를 iCloud 서버로 전송한다. 첫 번째 단계는 문서 이름, 수정 날짜, 파일 크기 및 파일 형식과 같은 정보를 포함하는 문서의 메타데이터를 보내는 것이다. 이 메타데이터 전송은 신속하게 이루어진다. 두 번째 단계는 문서의 데이터를 보내는 것이다. 먼저 문서 메타 데이터를 보내면 iCloud가 새 문서가 있음을 신속하게 알 수 있다. iCloud 서버는 새로운 메타데이터와 변경된 메타데이터를 같은 iCloud 계정에 연결된 사용 가능한 다른 모든 기기로 신속하게 증식시킨다. 이렇게하면 각기기가 새 문서가 있음을 알수있다.

그림 3-2  iCloud로의 파일 전송 첫실행
그림 3-2  iCloud로의 파일 전송 첫실행

문서의 데이터가 서버에 저장되고나면 iCloud는 향후의 기기 간 전송을 최적화한다. iCloud는 파일이 변경 될 때마다 전체 파일 또는 파일 패키지를 보내기보다는 메타데이터와 변경된 부분 만 보낸다. Figure 3-3은 이러 증분 업로드를 시각적으로 보여준다. 이전과 마찬가지로 시스템은 파일 메타데이터를 먼저 전송해서 iCloud가 메타데이터를 다른기기에 전파 할 수 있게한다. 메타데이터를 전송 한 후 시스템은 문서의 변경된 부분만 업로드한다. 이 최적화는 iCloud 네트워크 트래픽을 줄이고 기기가 소비하는 전력량을 줄인다. 아래 ‘네트워크 전송 효율을 위한 설계에 설명된 것처럼 당신은 이런 증분 전송을 지원하는 파일 형식을 설계하여 이러한 최적화를 도울 수 있다.

그림 3-3  파일의 변경사항만 iCloud에 전송하기
그림 3-3  파일의 변경사항만 iCloud에 전송하기

새 파일이 iCloud에 나타나면 아래의 그림 3-4와 같이 해당 파일을 사용자의 다른 장치에 다운로드해야한다. 각 장치에 대해 iCloud는 먼저 문서의 메타데이터를 보내서 장치가 파일의 존재를 알 수 있도록한다. 그 후에, 파일 데이터를 검색하는 타이밍은 장치 유형에 따라 다르다. iOS에서 앱은 시스템에 파일을 다운로드하도록 명시 적 또는 묵시적으로 요청해야한다. NSFileCoordinator 클래스의 메서드를 사용하여 해당 파일에 접근하여 암시 적으로 파일을 다운로드하거나 NSFileManager 클래스의 startDownloadingUbiquitousItemAtURL:error: 메서드를 호출하여 파일을 명시 적으로 다운로드한다. Mac은 서버에서 파일을 감지하자마자 자동으로 파일을 다운로드한다. 이러한 이유 때문에 Mac을 “탐욕스러운 응시(greedy peer)” 라고도 불린다. 만일 당신의 Mac 앱에서 새 문서의 메타데이터를 볼 수는 있지만 문서 자체가 로컬이 아닌 경우 시스템이 당신 앱을 대신하여 이미 다운로드 한 것일 수 있다.

 

그림 3-4 iCloud에서 처음으로 파일 받기
그림 3-4 iCloud에서 처음으로 파일 받기

파일의 내용물을 처음으로 다운로드 한 후, 후속 작업으로 아래의ㅣ 그림 3-5에 보여주는 것과 같이 파일의 변경된 부분 만 다운로드한다. 모든 전송과 마찬가지로 전송 프로세스의 첫 번째 단계는 해당 파일에대한 업데이트 된 문서의 메타데이터를 다운로드하는 것이다. 메타 데이터를받은 후 장치는 적절한 시간에 자동으로 변경 사항을 가져온다. iOS 기기에서는 파일을 소유 한 앱이 실행될 때(foreground)와 같은 적절한 시간에 변경 사항이 적용된다. OS X에서는 변경 사항이 즉시 적용된다.

그림 3-5  iCloud에서 변경된 데이터 받기
그림 3-5 iCloud에서 변경된 데이터 받기

파일의 업로드 또는 다운로드 진행률을 확인하려면 해당파일과 상응하는 NSURL객체에서 NSURLUbiquitousItemDownloadingStatusKey의 값을 검색하라. 이 키의 값은 해당파일이 이미 장치의 로컬에 있는지 다운로드 중인지 여부를 알려준다. NSURL 객체의 다른 속성을 가져와서 다운로드 진행에 대한 구체적인 데이터를 받을 수 있다. 관련 키의 목록은 NSURL Class Reference을 참조할 것

 

iCloud 문서 사용에 대한 앱의 책임

당신 앱의 문서에 대한 변경 사항은 언제든지 iCloud에서 올 수 있으므로 당신앱은 반드시 그것들을 처리할 준비가 되어있야한다. OS X의 NSDocument 클래스가 이 작업을 대부분 하지만 iOS에서는 당신이 명시 적으로 처리 하는 것이 더 있다. iOS 및 OS X 앱을 구현할 때 다음 아래것들을 수행하여 당신앱이 iCloud를 적절하게 처하도록 할 것.

  •  자동 저장(Auto Save)을 사용. 앱은 반드시 자동 저장이 iCloud에 사용에 관여되도록 해야한다. iOS에서는 기본 NSUndoManager 객체에 등록하거나 적절한 시간에 UIDocument의 updateChangeCount: 메소드를 호출하여 자동 저장을 사용하도록 설정한다. 예를 들어 뷰가 화면 밖으로 벗어나거나 앱이 백그라운드로 전환 될 때 updateChangeCount :를 호출 할 수 있을 것이다. OS X에서는 당신의 NSDocument 서브 클래스의 메써드인 autosavesInPlace 를 오버라이딩 하고 YES를 리턴하여 자동 저장을 활성화한다. • 자동 저장(Auto Save)을 사용. 앱은 반드시 자동 저장이 iCloud에 사용에 관여되도록 해야한다. iOS에서는 기본 NSUndoManager 객체에 등록하거나 적절한 시간에 UIDocument의 updateChangeCount: 메소드를 호출하여 자동 저장을 사용하도록 설정한다. 예를 들어 뷰가 화면 밖으로 벗어나거나 앱이 백그라운드로 전환 될 때 updateChangeCount :를 호출 할 수 있을 것이다. OS X에서는 당신의 NSDocument 서브 클래스의 메써드인 autosavesInPlace 를 오버라이딩 하고 YES를 리턴하여 자동 저장을 활성화한다.

 

  • iOS에서는 파일 시스템에서 문서의 위치를 능동적으로 추적한다. 당신의 iOS 앱의 각 인스턴스는 다른 인스턴스가 iCloud 기반 문서를 이동, 이름 바꾸기 또는 삭제하는 것에대한 준비되어야한다. 만일 당신 앱이 파일 또는 파일 패키지로의 URL 또는 경로 정보를 저장한다면, 다음번에 파일에 접근하려고 할 때 해당 항목이 같은 위치에 있을 것이라고 가정하지 말 것. • iOS에서는 파일 시스템에서 문서의 위치를 능동적으로 추적한다. 당신의 iOS 앱의 각 인스턴스는 다른 인스턴스가 iCloud 기반 문서를 이동, 이름 바꾸기 또는 삭제하는 것에대한 준비되어야한다. 만일 당신 앱이 파일 또는 파일 패키지로의 URL 또는 경로 정보를 저장한다면, 다음번에 파일에 접근하려고 할 때 해당 항목이 같은 위치에 있을 것이라고 가정하지 말 것.

iOS에서는 file coordination과 함께 NSMetadataQuery 객체를 사용하여 당신 문서의 위치를 ​​능동적으로 추적하도록 하라. 앱 실행 프로세스의 초기 단계에서 메타 데이터 쿼리 객체를 인스턴스화 및 구성하고, 그것을 시작하고 NSMetadataQueryDidUpdateNotification 알림에 등록하하라. presentedItemDidMoveToURL: 메써드와 presentedItemURL 프라퍼티를 구현하여 앱이 iCloud로부터 푸시 된 변경 사항에 대응 할 수 있도록하라. 당신 앱의 모델 레이어를 업데이트하고 필요에 따라 앱의 UI 요소도 업데이트할 것.

메타데이터 쿼리 사용에 대한 자세한 내용은 File Metadata Search Programming Guide를 참조할 것.

  • OS X에서는, 파일 시스템의 문서 위치를 ​​능동 적으로 추적하지 말 것. 문서 기반 Mac 앱의 열기 및 저장 대화 상자는 iCloud 기반의 문서 위치를 ​​자동으로 추적한다. 당신은 일반적으로 NSMetadataQuery 객체를 사용할 필요가 없다. 예를 들어 사용자가 한 기기에서 작업하면서 문서의 이름을 변경하거나 이동하면 다른 기기에서 실행중인 당신 앱의 인스턴스는 설계된 문서 구조에 의해서 자동으로 해당 변경사항을 가져온다.

 

  • iOS에서는 필요할 때 적극적으로 파일을 다운로드하라. iOS의 파일은 자동으로 다운로드되지 않는다. 새로운 iCloud 기반의 문서를 처음 다운로드하려면 주의를 기울이고 신중한 앱 디자인이 필요하다. 이러한 항목을 명시 적으로 다운로드하면 시스템은 자동으로 변경 사항을 다운로드한다

당신의 iOS 앱 모델 레이어의 일부로서 파일 다운로드 상태를 추적하는 것이 좋다. 이 정보가 있으면 더 나은 사용자 경험을 제공 할 수 있다: 아직 로컬이 아닌 문서를 열려고 할 때 긴 지연시간으로 인해 사용자를 놀라게하지 않도록 앱을 디자인 할 수 있다. 앱의 메타데이터 쿼리에서 제공하는 각 파일 (또는 파일 패키지) URL에 대해 NSURLUbiquitousItemDownloadingStatusKey 키의 값은 파일이 최신인지 여부 또는 다운로드 중인지 여부를 알려준다. 이 키의 값을 얻으려면 NSURL의 getResourceValue : forKey : error : 메소드를 호출 할 것. 다운로드되지 않은 파일을 읽는 데는 시간이 오래 걸릴 수 있다. 왜냐하면 다운로드를 완료하거나 실패가 확정될때까지 조정된 읽기 작업(oordinated read operation)이 이를 가로막기 때문이다.

아직 로컬이 아닌 파일 (또는 파일 패키지)에 대해, 사용자가 파일을 요청할 때 또는 파일이 필요할 것으로 예상될 때 미리 다운로드를 시작할 수 있다. 파일 수가 적고 각 파일 자체가 상대적으로 작으면 당신의 메타데이터 쿼리에 표시된 모든 파일을 적극적으로 다운로드하는 것을 고려할 수 있을 것이다. 쿼리에서 제공하는 각 파일 (또는 파일 패키지) URL에 대해 NSFileManager의 메서드 startDownloadingUbiquitousItemAtURL : error :를 호출하여 해당 항목을 로컬파일로 만들 것. 이미 로컬인 항목에 대한 URL을 이 메서드에 전달하면 메서드는 어떠한 작업도 수행하지 않고 YES를 반환한다.

  • iOS에서는 필요에 따라 버전 충돌을 처리하고 해결하라. 두 개의 다른 기기에서 실행 중인 당신앱의 두 인스턴스가 문서 변경을 시도 할 때 충돌이 발생한다. 예를 들어, 두 개의 장치가 네트워크에 연결되어 있지 않고 사용자가 두 장치를 변경 한 다음 두 장치를 네트워크에 다시 연결하면 이 문제가 발생할 수 있다. 충돌은 NSFileVersion 객체를 사용하여 앱에보고된다. iOS 문서 아키텍처는 우선시해야할 NSFileVersion 객체를 지명하여 충돌 해결을 관리하지만 제안된 버전을 수락하거나 다른 버전을 지정하는 것은 앱이 담당한다. 당신은 대부분 이 자동 추천에 의존 할 수 있다. 그러나, 당신의 앱은 필요할 때 도움을 줄 수 있어야한다.

iOS 문서의 상태가 변경되면 UIDocumentStateChangedNotification 알림 발송된다. 이 알림을 받으면 해당 문서의 documentState 프라퍼티의 값이 UIDocumentStateInConflict인지 확인할 것. 명시 적 해결책이 필요하다고 판단되면 NSFileVersion 클래스를 사용하여 충돌을 해결할 것. 필요한 경우 사용자에게 물을 것. 필요하다면 가능한 경우 사용자 개입없이 충돌을 해결할 것. 같은 iCloud 계정에 연결된 다른 기기에서 실행중인 당신 앱의 다른 인스턴스가 현재의 로컬 인스턴스보다 먼저 충돌을 해결할 수 있다는 것을 상기할 것.

충돌을 해결했으면 문서의 기한이 지난 옛 버전은 삭제하라. 그렇지 않으면 사용자의 iCloud 저장소에서 불필요하게 용량을 소비하게된다.

  • OS X에서는 시스템 충돌을 해결하기 위해 시스템에 의존하라. OS X은 문서를 사용할 때 충돌 해결을 관리한다.
  • OS X에서는 modal UI 요소로인해 교착상태에 빠지지 않도록 할 것. 같은 문서에 대한 프린팅 대화상자같은 경우처럼 당신의 앱이 modal 인터페이스를 표시하는 동안에 iCloud에서 문서변경사항을 수신할 수도 있다.

중요: document-modal 인터페이스 요소를 표시하는 동안 교착상태에 빠지지 않으려면 당신의modal UI 호출이 NSDocument의 performActivityWithSynchronousWaiting : usingBlock : 메서드 내에서 이루어지도록 할 것.

  • 항상 file coordinator를 사용하여 iCloud 파일 또는 파일 패키지에 액세스할 것. 문서 객체는 file coordinators를 자동으로 사용하는데, 이것은 iCloud를 디자인 하기위해 문서를 사용하는 것의 큰 이점 중 하나이다. • 항상 file coordinator를 사용하여 iCloud 파일 또는 파일 패키지에 액세스할 것. 문서 객체는 file coordinators를 자동으로 사용하는데, 이것은 iCloud를 디자인 하기위해 문서를 사용하는 것의 큰 이점 중 하나이다.

하지만 문서 기반 iOS 앱은 문서의 기본 파일에서 작업 할 때 file coordinator를 명시 적으로 사용해야한다. 다시말해서 파일을 이동, 이름 변경, 복제 또는 삭제할 때등이다. 이러한 작업의 경우 file coordinator의 쓰기 메써드의 문맥 안에서 메써드를 사용하라. 자세한 내용은 File System Programming Guide의 The Role of File Coordinators and Presenters를 참고.

대부분의 문서 기반 OS X 앱은 문서를 열거나 저장할 때 나타나는 ‘내장 된 앱-중심의 문서보기 UI(app-centric document viewing UI)’를 사용해야 할 것이다. 당신의 OS X 앱이 프로그래밍 방식으로 문서를 사용자에게 제시해야하는 경우에도 문서를 프로그래밍 방식으로 이동, 이름 바꾸기 또는 삭제하지 말 것. 이러한 작업을 수행하는 것은 Finder, OS X 기본 이름변경 UI, 또는 파일 메뉴의 기본 iCloud “이동” 메뉴를 사용하는 사용자의 몫이다.

  • 사용자가 실수로 정보를 공유하지 못하게 할 것. iOS 사용자와는 달리 OS X 사용자는 파일 시스템에 직접적으로 접근할 수 있다. 결과적으로, 사용자는 파일을 조작하고 앱의 범위 밖에서 콘텐츠를 볼 수 있다. 파일형식을 디자인할 때 예를 들어 이메일 버전의 문서처럼 사용자가 공유하지 않을 정보를 신중하게 고려할 것. 당신의 파일 또는 파일 패키지안에 그런 정보를 저장하기보다는 iCloud 컨테이너의 Documents 디렉토리 밖에 저장할 것(그림 1-2 참고)
  • 적절한 경우 문서를 사용자가 관리 할 수있게 만들 것. 파일을 iCloud 컨테이너의 Documents 하위 디렉토리에 두어 사용자가 볼 수있게하고 사용자가 개별적으로 파일을 삭제할 수있게하라. Documents 디렉토리 외부에있는 파일은 “data”로 그룹화된다. 사용자가 시스템 환경 설정 (OS X) 또는 설정 (iOS)에서 사용자의 iCloud에서 내용을 삭제할 수 있다. Documents 디렉토리 밖에있는 파일은 단일 그룹(monolithic group)으로서만 사용자에 의해서 삭제될 수 있다.

Documents 디렉토리를 사용할지 여부는 당신의 앱 디자인에 따라 다르다. 예를 들어, 당신앱이 사용자가 문서를 만들고 이름을 지정하도록 지원하는 경우 해당 문서 파일을 Documents 디렉토리에 넣을 것. 당신 앱이 사용자가 개별 문서 파일을 조작 할 수 없게하는 경우 Documents디렉토리 외부에 파일을 배치하는 것이 더 적절하다.

 

iCloud를 위한 문서 파일 포맷 디자인하기

당신의 문서 형식을 설계 할 때 선택하는 사항은 앱의 문서에 대한 네트워크 전송 성능에 영향을 미칠 수 있다. 가장 중요한 선택은 당신의 문서 형식을 위한 파일 패키지를 사용해야한다는 것이다.

당신의 iOS 및 Mac 용 앱 버전을 모두 제공하는 경우, 문서 파일 형식이 플랫폼 간 호환이 가능하도록 디자인할 것.

 

네트워크 전송 효율을 위한 설계

당신의 문서 데이터 형식이 여러개의 고유한 부분으로 구성된다면, 문서 파일 형식에 파일 패키지(file package)를 사용하라. NSFileWrapper 객체를 통해 접근하는 파일 패키지를 사용하면 별도로 읽고 쓸 수있는 개별 파일 및 폴더로서 문서의 요소를 저장하면서도 사용자에게는 단일 파일로 표시 할 수 있다. iCloud 업로드 및 다운로드 절차는 파일 패키지 내 컨텐츠의 이러한 인자를 이용한다: 변경된 요소 만 업로드하거나 다운로드한다.

Xcode의 앱 Info.plist 파일에 당신의 문서 파일 포맷, 그리고 그 것과 관련된 파일이름 확장자를 등록하하라. 특히, CFBundleDocumentTypes 키를 사용해서 당신 앱이 인식하고 열 수있는 파일 포맷을 지정하하라. 해당 파일 내용에 상응하는 파일 확장명과 UTI (uniform type identifier)를 모두 지정하라. 시스템은이 정보를 사용하여 파일 패키지를 앱에 연결하고, OS X에서는 일반 파일 인 것처럼 파일 패키지를 사용자에게 표시한다.

 

지속되는 문서 상태정보 설계

여러 문서기반 앱들은 문서 단위로 상태를 유지함으로써 장점을 갖는다. 예를들어, 벡터기반의 그리기 앱의 사용자는 각 문서에서 가장 최근 사용한 그리기 도구를 사용했고 어떤 요소가 선택되었었는지 기억되길 원할 것이다.

 

문서별 상태를 저장할 수 있는 장소는 두곳이 있다:

  • 문서의 파일 패키지(또는 플랫 파일 형식) 안. 이 경우, 예를 들어서 사용자가 문서를 이메일에 첨부할 때 해당 문서와 문서상태를 함께 유지하는 것을 지원한다.
  • 문서와 연결되지만 파일패키지(또는 파일 포맷) 밖. 이 경우 사용자가 정보를 공유하길 원하지 않는 경우를 지원한다. 하지만 당신의 문서객체에의해서 관리되는 데이터의 밖에 있게되면 문서상태는 문서충돌 해결 기능으로 추적할 수 없고 전적으로 당신에게 달려있다.

참고: 대부분의 경우 Key-value storage는 문서단위 상태를 저장하는데 적합하지 않다. 시스템이 key-value와 document 두 타입의 스토리지에 데이터를 업로드하고 다운로드하는 방식이 다르고 각 스토리지에 접근하기위한 API가 다르기 때문이다.

어떤 방식을 선택하든지 편집하는 기능을 지원하는 앱에서 문서가 편집되지 않는한 문서상태를 저장하지 않도록 주의 할 것. 그렇지않으면 네트워크 대역폭 및 배터리 전원을 소비하는 사소하고 도움되지않는 충돌 시나리오를 겪게된다.

예를 들어, 사용자가 자신의 iPad에서 긴 텍스트 문서의 1 페이지를 편집하고 있었다고 생각해보자. 잠시 후, 그녀는 iPhone에서 문서를 열고 마지막 페이지로 스크롤한다. 이 좋지않은 동작을 하는 예제 앱은 사용자가 문서를 편집하지 않았더라도 문서 끝 스크롤 위치를 적극적으로 저장한다. 사용자가 나중에 iPad에서 문서를 열어 편집을 다시 시작하면 스크롤 위치를 나타내는 상태 데이터 때문에 불필요한 충돌이 발생한다. 시스템은 충돌 (UIDocumentStateInConflict)로 문서를 표시하고 최신 버전 (자동으로 충돌시 우선 데이터(conflict winner)로 지명 됨)은 마지막 페이지로 스크롤된 문서가 된다. 훌륭한 동작을 가진 iCloud 앱이려면, 이 텍스트 편집기는 iPhone에서 사용자가 콘텐츠를 편집하지 않고 스크롤만 변경한 것은 무시했어야 했을 것이다.

 

앱의 다양한 사용 시나리오를 생각해보고 그에 따라 사용자 경험을 향상 시킬 것. 다음과 같은 상태정보에 주의를 기울여보자:

  • 문서 스크롤 위치
  • 선택된 요소
  • 마지막으로 열람한 시간
  • 표 정렬 순서
  • 윈도우 창 사이즈 (OS X)

고려해야 할 전략은 사용자가 변경한 것이 저장할 가치가있는 경우에만 그런 상태정보를 저장하는 것이다. OS X에서 기본 제공되는 이력서 기능은 대부분의 문서 기반 앱이 필요로하는 모든 상태 저장에 대한 동작을 제공한다다. 추가 제어가 필요한 경우 NSChangeDiscardable 문서 변경 타입을 이용할 수 있다.

 

견고성 및 크로스 플랫폼 호환성을위한 설계

iCloud 용 문서 파일 포맷을 디자인 할 때 다음 요소를 염두에 두자:

  • 플랫폼 간 데이터 표현을 사용한다. 이름이 같은 클래스 (iOS의 경우 ‘UI’, OS X의 경우 ’NS’ 같은 접두사가 붙은 것들)는 직접적으로 호환되지 않는다. 이것은 다른 클래스뿐만 아니라 색상 (UIColor 및 NSColor), 이미지 (UIImage 및 NSImage) 및 베지에이 패스 (UIBezierPath 및 NSBezierPath)역시도 그렇다.

예를 들어 OS X의 NSColor 객체는 색상 공간 (NSColorSpace)의 관점에서 정의되지만 iOS에는 색상 공간 클래스가 없다.

당신의 문서 포맷 프로퍼티에 이러한 클래스를 사용하는 경우 아래 그림 3-6에 나타낸 것처럼 두 플랫폼 중 하나에서 네이티브 표현으로 충실하게 재구성 할 수있는 중간단계의 iCloud 데이터표현을 고안해야한다. NSDocument 객체가 데이터를 디스크에 저장하면 (단계 1) 각 플랫폼 별 데이터 유형이 중간 크로스 플랫폼 데이터표현으로 변환된다. 이 크로스 플랫폼 데이터는 iCloud에 저장되고 사용자의 다른 기기에 다운로드된다 (2 단계 및 3 단계). 앱의 iOS 버전에서 해당 데이터를 추출하면 (4 단계) 크로스 플랫폼 데이터표현의 데이터를 iOS 전용 버전으로 변환한다.

 

그림 3-6  크로스플랫폼 데이터표현 사용하기
그림 3-6  크로스플랫폼 데이터표현 사용하기

나중에 어느 플랫폼에서나 볼 수 있도록 iOS 앱에서 문서를 저장할 때, 플랫폼 간 데이터 표현을 사용하여 iOS 문서를 저장함으로써 그림 3-6에 나타낸 절차를 반대로 하면된다.

당신의 문서 포맷에 채택하는 각각의 플랫폼에 한정된 데이터타입에 대해 양쪽 플랫폼에서 공유될 수 있는 적절한, 로우레벨 데이터타입의 중간단계 데이터표현을 사용가능한지 확인하자. 예를들어, 각 색상클래스(UIColor 와 NSColor)에는 Core Image의 CIColor 인스턴스로부터 색상 객체를 생성할 수 있는 초기화 메써드가 있다.

iCloud에 기록할 데이터를 준비할 때 중간단계 데이터표현으로 변환하고 iCloud기반의 파일을 읽을 때 그 중간단계 데이터표현을 변환하자. NSCoder 또는 그것에 기반한 서브클래스의 메써드를 호출하여 문서의 객체 그래프를 인코딩, 디코딩한다면 그런 메써드 안에서 이런 변환작업을 수행하자.


  • 플랫폼 별 좌표계를 고려할것. iOS 및 OS X의 기본 화면 좌표계는 서로 다르므로 UI를 그리는 방법과 뷰를 배치하는 방법이 다르다. 교차 플랫폼 데이터표현으로 화면 좌표 정보를 저장하고 추출 할 때 이를 고려할 것. 자세한 내용은 Drawing and Printing Guide for iOS에서 Coordinate Systems and Drawing in iOS을 참조.
  • 항상 대소문자를 구분하지 않는 파일 이름을 사용할 것. OS X는 기본적으로 거의 모든 사용자에대해 대소문자를 구분하지 않는 파일 시스템을 사용한다. 예를 들어, mydoc.txt 파일과 MyDoc.TXT 파일은 OS X의 동일한 디렉토리에 존재할 수 없다. 대조적으로, iOS는 파일 이름을 다르게 취급한다. 당신의 문서 파일 포맷이 플랫폼 간 호환이 가능하도록하려면, 파일을 대소문자를 구분하지 않고 작성하도록 할 것.
  • 포맷 버전 번호를 사용하자. 나중에 문서 포맷을 변경하려면 포맷 버전 번호 매기기 구성표를 설계하고 버전 번호를 문서 포맷의 프라퍼티로서 적용하자.

당신의 문서 포맷에 버전을 매기는 것은 항상 좋은 생각이고, iCloud 및 크로스 플랫폼 포맷의 경우 더욱 중요하다. 예를 들어, iCloud 사용자는 콘텐트를 볼 수 있는 여러 기기를 보유할 가능성이 있다. 하지만 사용자의 기기에있는 당신의 모든 앱 인스턴스를 성실하게 한번에 업데이트 하지 않을 수 있다. 예를들어 사용자의 Mac에는 당신앱의 최신버전을 설치하고 있을 수 있지만 iPad에는 1년전 버전을 가지고 있을 수 있는 것이다.

당신의 초기 버전의 앱은 iOS 전용 일 수 있고 나중에 OS X 버전을 배포 할 때 문서 포맷을 수정하려고 할 것이다. 각 문서 내에 포맷 버전 정보를 포함시킴으로써 당신은 버전에 관계없이 문서를 정상적으로 처리 하고 싶을 것이다. 예를 들어, OS X 앱에서는 오래된 iOS앱 전용 포맷을 읽기 전용으로 설정할 수 있겠다. 각 플랫폼마다 여러 버전의 앱이 실행되는 여러 가지 시나리오를 생각해 볼 것. iCloud 기반 문서에 대해 최상의 사용자 경험을 제공하도록 하자.

파일 포맷을 디자인하는 기술에 대한 자세한 정보는 Document-Based App Programming Guide for iOS의 Choosing Types, Formats, and Strategies for Document Data 또는  Document-Based App Programming Guide for Mac의 Handling a Shared Data Model in OS X and iOS을 읽어볼 것.

 

문서기반의 작업흐름(워크플로우)

표 3-1은 문서 기반 앱의 일반적인 워크플로우를 나열하고있다. 각 워크플로우에 대해 테이블에는 해당작업의 간단한 설명과 함께 일반적으로 사용하는 기본 클래스가 나열되어있다.

작업흐름구현설명
새 표준문서 만들기UIDocument (iOS)

NSDocument (OS X)
당신의 문서포맷안에 문서객체를 사용해 데이터구조를 생성하고 관리. 해당 문서 클래스는 자동으로 새로운 문서를 iCloud 컨테이너 또는 로컬 저장소에 저장하기를 지원한다.
새로운 Core Data 문서 생성UIManagedDocument (iOS)

NSPersistentDocument (OS X)
Core Data 문서 서브클래스를 사용해서 당신의 Core Data 저장소를 생성하고 관리. 사제한 설명은 Designing for Core Data in iCloud을 참고
iCloud 문서 URL 가져오기NSMetadataQuery (iOS)

자동 (OS X)
iOS에서는 메타데이터 쿼리 객체를 사용하여 iCloud 문서에서 실시간 업데이트 정보를 찾는다. OS X v10.8 이상에서는 문서의 ‘열기’ 대화 상자가 자동으로 메타데이터 쿼리를 사용한다.
사용자가 문서를 열도록 하기iOS: 커스텀 UI
OS X: 문서 설계구조의 일부로서 자동
iOS에서 앱 디자인과 잘 어울리는 간단하고 명확한 방법으로 사용자 문서에 대한 선택 UI를 당신이 직접 제공해야한다. OS X v10.8 이상에서, 문서 기반 앱의 ‘열기’ 명령은 사용자가 iCloud 파일을 선택할 수있는 대화 상자를 표시한다.
버전충돌 해결UIDocument, NSFileVersion (iOS)

자동 (OS X)
iOS에서 문서는 충돌을 감지하고 알려준다. 필요에 따라 NSFileVersion 객체 (문서의 리비전 버전 당 하나)를 사용하여 이를 해결할 것.
iCloud 기반 문서를 이동,복사, 삭제NSFileCoordinator
또는
NSFileManager
NSFileManager클래스를 사용해서, 그리고 항상 file coordinator 객체의 문맥안에서 디스크의 파일을 조작

위의 작업흐름을 실행하는 방법에대한 자세한 사항은 당신이 목표로 하는 플랫폼에 대한 문서기반 프로그래밍 가이드를 읽어 볼 것. iOS는  Document-Based App Programming Guide for iOS를, Mac은 Document-Based App Programming Guide for Mac를 읽어 볼 것.

 

아이클라우드 드라이브의 Document 스토리지 활성화하기

당신의 문서를 iCloud Drive에 저장하려면 Xcode의 Capabilities 섹션에서 iCloud를 활성화하고 Info.plist파일에 NSUbiquitousContainers 키를 추가하라.

Mac 참고사항: OS X v10.11 이상에서, Xcode 프로젝트에 ID를 서명하거나 iCloud를 활성화할 필요없이 사용자의 iCloud Drive 폴더에 문서를 저장할 수 있다.  Info.plist 파일에 당신앱의 컨테이너를 명시하면된다.

당신앱의 컨테이너를 명시하려면 앱의 컨테이너 ID에  NSUbiquitousContainers키를 설정하라. 또한, 다른  NSUbiquitous… 키들을 사용해서 각 컨테이너를 어떻게 공유하길 원하는지 명시하라

<key>NSUbiquitousContainers</key>
   <dict>
      <key>iCloud.com.example.MyApp</key>
      <dict>
         <key>NSUbiquitousContainerIsDocumentScopePublic</key>
         <true/>
          <key>NSUbiquitousContainerSupportedFolderLevels</key>
          <string>Any</string>
          <key>NSUbiquitousContainerName</key>
          <string>MyApp</string>
      </dict>
   </dict>

이런 세팅을 사용하면 당신앱의 컨테이너안에 저장된 파일에대한 공개적 접근을 iCloud Drive가 제공할 수 있게 해준다. 그런 문서를 저장할 수 있도록 iCloud Drive는 사용자의 iCloud Drive 폴더안에 당신앱의 폴더를 생성할 것이다.  NSUbiquitous… 키들에 대한 자세한 설명은  Information Property List Key Reference의 Cocoa Keys를 참고.

2 댓글

댓글은 익명이나 SNS, wordpress.com 로그인 지원). 마크다운 문법 사용가능(Shift+~ 키로 특정문구 혹은 위아래 ~~~으로감싸서 여러줄을 코드블락으로 작성)