"Keep the local and remote copies of your File Provider extension’s content in sync."
싱크에서 파일 제공자 컨텐트의 로컬 및 원격 복사본을 유지합니다.
시스템은 파일 제공자의 원격 저장소에 저장된 아이템(문서 및 폴더 모두)의 로컬 복사본을 관리합니다. 로컬 복사본은 dateless 혹은 이 아이템의 구체화된 복사본을 포함할 수 있습니다. dataless 복사본은 UI에서 표시할 필요가 있는 아이템 정보만을 저장하는 반면 구체화된 복사본은 아이템의 컨텐트를 포함합니다.
문서에서 dataless 복사본은 시스템이 아이템의 메타데이터(데이터의 이름, 파일 크기, 최근 사용 일자와 같은)만을 저장한다는 것을 의미합니다. 반면에 구체화된 문서는 메타데이터와 컨텐트 모두를 포함합니다. 폴더의 경우 더 추상적입니다. dataless 폴더의 경우 시스템은 폴더가 존재한다는 것을 알고 있지만 컨텐트를 아직 열거하지 않습니다. 만약 사용자가 폴더를 열면, 시스템은 사용자에게 표시하기 전에 컨텐트를 열거할 필요가 있습니다. 구체화된 폴더는 시스템이 이미 열거된 폴더를 갖고 있음을 의미합니다. 그러므로 시스템은 폴더에서 모든 아이템의 dataless 혹은 구체화된 복사본을 갖고 있고, 추가적인 정보 요청 없이 폴더의 컨텐트를 표시할 수 있습니다.
시스템은 디스크 공간 및 밴드위스 모두에 보존할 가능성이 있는 곳에서 dataless 복사본을 사용합니다. 그러나 사용자는 구체화된 복사본을 즉시 열 수 있으며, 원격 저장소에 추가적인 접근 요청 없이 열 수 있습니다. 그러므로 사용자가 자주 접근하려고 하거나 오프라인일 때에도 모든 아이템의 구체화된 복사본을 유지하는 것은 중요합니다. 더 자세한 정보는 Specify the Working Set을 살펴보시기 바랍니다.
Specify the Working Set은 이 글의 아래에 나옵니다.
시스템은 원격 저장소의 컨텐츠에 대한 추가적인 정보가 필요할 때마다 확장과 소통합니다. 예를 들어 사용자가 새 폴더를 열 때마다 시스템은 enumerator(for:request:)
를 호출해서 해당 폴더를 채울 수 있도록 합니다.
응답에서 파일 제공자는 NSFileProviderEnumerator
프로토콜을 채택하는 객체를 생성해야 합니다. 그러면 이 객체는 메소드의 containerItemIdentifier
에 구체화된 컨테이너의 컨텐츠를 제공합니다. 컨테이너는 파일 제공자의 루트 폴더가 될 수 있고, 루트 폴더의 하위 폴더도 될 수 있으며, 휴지통 혹은 작업하고 있는 집합(사용자에게 특별히 관련이 있는 파일의 집합)이 될 수도 있습니다.
시스템이 컨텐트를 받을 때 시스템은 각 아이템에 대한 dataless 복사본을 열거자에 의해 제공된 NSFileProviderItemProtocol
객체가 갖고 있는 메타데이터에 기반해 저장합니다.
시스템은 dateless 복사본을 필요한 경우 구체화된 복사본으로 변환할 수 있습니다. 예를 들어 만약 사용자가 dataless 파일을 열면, 시스템은 fetchContents(for:version:request:completionHandler:)
를 호출하고, 파일의 컨텐트를 저장합니다. dataless 폴더의 경우 시스템은 enumerator(for:request:)
를 호출해서 폴더의 컨텐트를 열거할 수 있도록 합니다.
시스템은 사용자 액셩 혹은 원격 저장소에서의 업데이트에 대한 응답으로써 정보를 요청합니다. 그러나 파이 제공자의 컨텐트 혹은 구체화된 아이템을 필요한 경우 열거할 수도 있습니다. 예를 들어 시스템은 스팟라이트가 인덱싱할 수 있도록 백그라운드에서 작업하고 있는 집합의 컨텐트를 열거하거나 구체화할 수 있습니다. 또한, 구체화된 아이템을 자유 디스크 공간에 dataless 아이템으로 변환할 수 있습니다.
Note
만약 아이템에 파일 제공자 확장이 싱크해야 하는, 보류 중인 변경사항을 갖고 있다면, 데이터 손실을 피하기 위해 시스템은 구체화된 아이템을 dataless로 변환하지 않을 것입니다.
작업하고 있는 집합은 사용자가 특별히 관심을 갖고 찾게 될 아이템의 리스트입니다. 파일 제공자는 고유한 작업하고 있는 집합을 유지해야 합니다. 파일 제공자에 대한 일관적인 경험을 위해서 작업하고 있는 집합은 보통 아래를 포함합니다.
만약 사용자에게 특별히 관련이 있다고 판단되는 경우 작업하고 있는 집합에 문서 혹은 폴더를 추가할 것입니다. 사용자 데이터의 일관적인 뷰를 제공하기 위해 모든 사용자 기기에 작업하고 있는 집합에 대한 모든 변경사항이 전달됩니다.
시스템이 로컬 복사본에 원격 업데이트를 적용하는 것을 보장하려면, 작업하고 있는 집합은 복제된 파일 제공자를 사용하는 경우 시스템에 의해 관리되는 모든 구체화된 아이템 역시 포함해야 합니다. 만약 파일 제공자가 구체화된 아이템을 명시적으로 추적하지 않는다면, 작업하고 있는 집합은 원격 저장소에 모든 아이템(문서 및 디렉토리)을 포함시켜야 합니다.
작업하고 있는 집합에 접근하기 위해 시스템은 workingSet
을 컨테이너 아이덴티파이어로써 전달하면서 파일 제공자 확장의 enumerator(for:request:)
메소드를 호출합니다.모든 아이템을 반환할 수 있고 작업하고 있는 집합을 변경시킬 수 있는 열거자를 제공해야 합니다.
다른 컨테이너와 다르게 사용자는 파일 제공자를 통해 탐색할 때 작업하고 있는 집합의 열거형을 드라이브하지 못합니다. 대신 시스템은 백그라운드에서 필요한 경우 작업하고 있는 집합을 업데이트합니다. 시스템은 작업하고 있는 집합의 컨텐트에 대한 구체화된 복사본을 저장합니다(사용자가 오프라인일 때 접근할 수 있도록 해주는). 기기의 스팟라이트 데이터베이스는 작업하고 있는 집합의 컨텐츠를 인덱싱합니다. 시스템은 작업하고 있는 집합의 변경사항을 알려줄 때마다 스팟라이트 데이터베이스를 업데이트합니다.
원격 업데이트가 발생할 때, 파일 제공자는 아이템 혹은 부모가 작업하고 있는 집합에 속하는 경우에만 시스템에 알려줄 필요가 있습니다. 원격 업데이트를 최적화하려면 파일 제공자 확장은 시스템이 아이템을 구체화하거나 dataless로 렌더링할 때 아이템을 추적할 수 있습니다. 이는 작업하고 있는 집합에 아이템을 추가하거나 제거하면서 이뤄집니다. 구체화된 아이템을 추적하지 않는 경우 작업하고 있는 집합은 원격 저장소에 모든 아이템을 포함시켜야 하며, 모든 변경사항에 대해 시스템에게 알려줘야 합니다. 시스템은 새 아이템을 구체화하거나 구체화된 아이템을 dataless로 렌더링할 떄, 파일 제공자의 materializedItemsDidChange(completionHandler:) 메소드를 호출합니다. 그러면 파일 제공자는 상응하는 도메인에 대해 파일 쩨공자 매니저에서 enumeratorForMaterializedItems()
를 호출함으로써 변경사항을 열거해야 합니다. 그리고 파일 제공자는 이전 싱크 지점 이후 변경사항 접근을 위해, 제공된 열거자를 사용합니다. 이러한 변경사항에 기반해 작업하고 있는 집합을 업데이트하시기 바랍니다.
사용자, 앱, 혹은 몇 가지 다른 이벤트가 원격 저장소에서 아이템을 생성, 수정, 삭제할 때, 파일 제공자 확장은 업데이트 신호를 보낼 필요가 있는지 여부를 결정하기 위해 작업하고 있는 집합을 확인해야 합니다. 만약 파일 제공자가 구체화된 아이템을 추적하지 않는다면, 작업하고 있는 집합은 원격 저장소에서 모든 아이템을 포함시키며, 모든 변경사항에 대한 업데이트 신호를 보내야 합니다.
구체화된 아이템을 추적하는 파일 제공자의 경우 아이템의 itemIdentifier
혹은 parentItemIdentifier
가 작업하고 있는 집합에 있는지 확인해야 합니다. 만약 일치하는 아이덴티파이어를 찾으면, 해당 아이덴티파이어에 대한 업데이트 신호를 보내야 합니다.
NSFileProviderManager
클래스의 signalEnumerator(for:completionHandler:)
메소드를 호출해야 합니다. containerItemIdentifier
속성으로써 일치하는 아이덴티파이어를 전달해야 합니다.signalEnumerator(for:completionHandler:)
를 두 번 호출해야 합니다. workingSet
속성을 containerItemIdentifier
속성으로써 전달해야 합니다. 이것은 시스템에게 작업하고 있는 집합을 업데이트할 것을 알려줍니다.아이템을 이동시킬 때 새 parentItemIdentifier
및 기존 parentItemIdentifier
를 확인해야 합니다. 만약 기존 parentItemIdentifier
가 작업하고 있는 집합에 있다면, 새 parentItemIdentifier
에 변경사항에 대한 신호를 보내야 합니다. 새로운 부모가 작업하고 있는 집합에 있지 않아도 그렇게 해야 합니다.
대안으로 파일 제공자 확장 호출 signalEnumerator(for:completionHandler:)
를 갖는 것 대신, 원격 저장소는 기기에 푸시 노티피케이션을 직접 보냄으로써 업데이트에 대한 신호를 보낼 수 있습니다. 더 많은 정보는 Using Push Notifications to Signal Changes를 살펴보시기 바랍니다.
Using Push Notifications to Signal Changes
https://developer.apple.com/documentation/fileprovider/content_and_change_tracking/tracking_your_file_provider_s_changes/using_push_notifications_to_signal_changes
https://velog.io/@panther222128/Using-Push-Notifications-to-Signal-Changes