iOS13でNSPersistentCloudKitContainerが登場しましたが、その後もiOS14とiOS15で順調にAPIが拡充されています。
この記事では、これらの同期イベントを監視するための方法を解説します。
通知を利用して同期イベントを監視する
NSPersistentCloudKitContainerにはiOS14から同期イベントの監視のためのAPIが登場しています。
(Apple Developer Documentationの同期イベント監視オブジェクト一覧1)
この記事では、この中のNSPersistentCloudKitContainer.eventChangedNotificationを利用して通知により同期イベントを取得します。
事前条件
- CoreData with CloudKitがセットアップされたプロジェクトがある。
Combineを利用して通知を受け取る
この記事ではCombineとして通知を受け取っていきます。print
を使って内容を出力することで中身を確認していくので、ここではprintObserver
という名前のAnyCancellable
を定義していきます。
private var printObserver: AnyCancellable? = nil
同期イベントの発生はNSPersistentCloudKitContainer.eventChangedNotificationを通知名としてNotificationCenterの監視APIを利用することで監視することができます。今回はCombineのpublisher(for:object:)を利用していますが、addObserver(_:selector:name:object:)でも同様に監視を行えます。
この通知のuserInfoにはEventオブジェクトが格納されており、NSPersistentCloudKitContainer.eventNotificationUserInfoKeyでアクセスすることによって取得できるように設計されています。
以下のサンプルでは取得したEventとそのインスタンスプロパティを1つずつ出力しています。
printObserver = notificationCenter
.publisher(for: NSPersistentCloudKitContainer.eventChangedNotification)
.sink(receiveValue: { notification in
let event = notification.userInfo?[NSPersistentCloudKitContainer.eventNotificationUserInfoKey] as! NSPersistentCloudKitContainer.Event
print("Reveiced cloudkit container's sync event: \(event)")
print("type: \(event.type.rawValue)")
print("identifier: \(event.identifier)")
print("storeIdentifier: \(event.storeIdentifier)")
print("succeeded: \(event.succeeded)")
print("startDate: \(event.startDate)")
print("endDate: \(event.endDate)")
print("error: \(event.error)")
})
この時、event.typeを参照することで、ローカルの変更をクラウドに送信したのかクラウドの変更をローカルに受信したのかを判別することができます。
/// The type of event in a persistent CloudKit container, either setup, import, or export.
enum EventType {
/// An event the persistent CloudKit container generates when setting up a store.
case setup = 0
/// An event the persistent CloudKit container generates when importing records into a store.
case `import` = 1
/// An event the persistent CloudKit container generates when exporting managed objects from a store.
case export = 2
}
どのように使うか?
例えば、イベント種類がimport
の際だけ、同期されたオブジェクトに対する事後処理を実装するなどが考えられます。(今自分で触ってどう使えるか確認しているところなので、まとまり次第追記します)
まとめ
この記事では通知を利用して同期イベントを監視する方法をお伝えしました。
- NSPersistentCloudKitContainer.eventChangedNotificationを利用して同期イベントに関する通知を受け取る。
- userInfo?[NSPersistentCloudKitContainer.eventNotificationUserInfoKey]でイベントオブジェクトを取得する。
- event.typeでどの種類のイベントが発生したか判定する。
何かうまくAPIの使い方などあればコメントで教えてください!
-
Apple inc., Monitoring Container Events, NSPersistentCloudKitContainer, https://developer.apple.com/documentation/coredata/nspersistentcloudkitcontainer, viewed: 2021/09/09 ↩