私は自分のアプリを Core Data で動作させ、次に CloudKit でデバイス間で同期させました。そして今、ユーザー間でデータを共有したいと考えています。「CloudKit と Core Data を介してデータを共有するアプリをビルドする」と「CloudKit WWDC21 の新機能」の両方を見て、概念が理解できたと思いました。CloudKit はゾーン共有と CKShares を使用して共有を処理し、Core Data は iOS15 でネイティブにこの実装にアタッチされます。
Core Data スタックを次のようにセットアップします。
/// Configure private store
guard let privateStoreDescription: NSPersistentStoreDescription = persistentContainer.persistentStoreDescriptions.first else {
Logger.model.error("Unable to get private Core Data persistent store description")
return
}
privateStoreDescription.url = inMemory ? URL(fileURLWithPath: "/dev/null") : privateStoreDescription.url?.appendingPathComponent("\(containerIdentifier).private.sqlite")
privateStoreDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
privateStoreDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
persistentContainer.persistentStoreDescriptions.append(privateStoreDescription)
/// Create shared store
let sharedStoreDescription: NSPersistentStoreDescription = privateStoreDescription.copy() as! NSPersistentStoreDescription
sharedStoreDescription.url = sharedStoreDescription.url?.appendingPathComponent("\(containerIdentifier).shared.sqlite")
let sharedStoreOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: containerIdentifier)
sharedStoreOptions.databaseScope = .shared
sharedStoreDescription.cloudKitContainerOptions = sharedStoreOptions
persistentContainer.persistentStoreDescriptions.append(sharedStoreDescription)
persistentContainer.loadPersistentStores(...)
SceneDelegate ユーザー受け入れを実装しました。
func windowScene(_ windowScene: UIWindowScene, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata) {
let container = PersistenceController.shared.persistentContainer
let sharedStore = container.persistentStoreCoordinator.persistentStores.first!
container.acceptShareInvitations(from: [cloudKitShareMetadata], into: sharedStore, completion: nil) //TODO: Log completion
}
ただし、以下に示すように、UI で NSObject をそのまま共有した後UICloudSharingController
:
let object: NSObject = // Get Object from view context
let container = PersistenceController.shared.persistentContainer
let cloudSharingController = UICloudSharingController { (controller, completion: @escaping (CKShare?, CKContainer?, Error?) -> Void) in
container.share([object], to: nil) { objectIDs, share, container, error in
completion(share, container, error)
Logger.viewModel.debug("Shared \(household.getName())")
}
}
cloudSharingController.delegate = self
self.present(cloudSharingController, animated: true) {}
SceneDelegate メソッドが呼び出されることはなく、メッセージ アプリから招待を押すと、次のアラートが表示されます。この場合、CloudKit 開発者コンソールで com.apple.coredata.cloudkit.share.[UUID] のゾーンを持つプライベート データベースにオブジェクトが表示されるため、何が問題なのかよくわかりません。私はまだアプリをリリースしていないので、両方のアプリが Xcode デバッガー (同じバージョンとビルド) から起動されたため、バージョン情報をどこから取得しているのかわかりません。さらに、他の質問に関するこのアラートの参照を見つけることができなかったので、アドバイス、提案、またはヘルプを歓迎します. この問題に光を当てることができる情報が他にあれば教えてください。