🎉
CKSyncEngineでデータをiCloudに同期する
WWDC23で発表されたCloudKitの新API
デバイスのローカルにあるデータとCloudKit(iCloud)の双方向な同期処理を簡単に実現できる機能
同期が必要な例としてはWeb→iPad→iPhone間で同じデータを更新したりとか
サンプルコード
このアプリではローカルに保存しているContacts.jsonの読み書きをCloudKitのRecordと同期する
let container: CKContainer = CKContainer(identifier: "iCloud.com.apple.samples.cloudkit.SyncEngine")
let dataURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appending(component: "Contacts").appendingPathExtension("json")
let appDataBlob = try Data(contentsOf: dataURL)
let appData = AppData()
var configuration = CKSyncEngine.Configuration(
database: container.privateCloudDatabase,
stateSerialization: appData.stateSerialization,
delegate: self
)
configuration.automaticallySync = true
let syncEngine = CKSyncEngine(configuration)
AppDataやContactはDataModelで定義された構造体
delegateはCKSyncEngineDelegateを実装したクラス、システムに非同期で呼び出される
同期処理のハンドリング
syncEngine.state.add()
して変更したRecordを送信するのが基本的な方法
delegateのhandleFetchedRecordZoneChanges()
で受け取った変更をContacts.jsonに保存する
handleSentRecordZoneChanges()
はマージ競合の解決
syncEngine.state.add(.deleteZone)
して削除
CKSyncEngineじゃないもの
CKDatabaseSubscription+APNsで自作
CKSyncEngineのアーキテクチャはこれと同様だと思う
NSPersistentCloudKitContainer
Core DataのストレージをCloudKitにミラーリングするやつ
ローカルにあるDBがCore Dataならこっちで代用できる
SwiftData+CloudKit
SwiftDataの基盤はCore DataなのでCloudKitへの同期をオプトインできる
Discussion