我使用NSPersistentCloudKitContainer将对象保存在CoreData + CloudKit中。我已经集成了一个共享函数,它将一个对象移动到一个单独的区域使用UICloudSharingController共享,如https://developer.apple.com/wwdc21/10015中所描述的
当用户停止共享时,我希望删除共享区域中的对象,并将其移回CoreData + CloudKit标准专用区域。删除CKShare及其区域使用以下方法:
/**
Delete the Core Data objects and the records in the CloudKit record zone associcated with the share.
*/
func purgeObjectsAndRecords(with share: CKShare, in persistentStore: NSPersistentStore? = nil) {
guard let store = (persistentStore ?? share.persistentStore) else {
print("\(#function): Failed to find the persistent store for share. \(share))")
return
}
persistentContainer.purgeObjectsAndRecordsInZone(with: share.recordID.zoneID, in: store) { (zoneID, error) in
if let error = error {
print("\(#function): Failed to purge objects and records: \(error)")
}
}
}如何在删除CKShare之前将其深入复制回私有区域?
发布于 2022-04-05 09:30:28
我不确定我是否理解你的意思,但我会试着回答:
假设私有数据库中的记录层次结构或区域应由所有者共享。
当共享启动时,将邀请用户共享数据,并在所有者的私有数据库中初始化CKShare记录。
当用户接受邀请时,用户可以通过用户的共享数据库访问CKShare记录和共享数据。它们不会复制到共享数据库;共享数据库只是所有者私有数据库的窗口。但是,如果共享数据库由CoreData + CloudKit镜像为共享用户的持久存储,则为共享数据创建NSManagedObjects。
当所有者或用户停止共享时,用户通常不能再访问这些NSManagedObjects。原则上,这也是由iCloud镜像处理的:共享数据库不再是所有者数据的窗口,也就是说,它不再包含CKShare记录和共享数据,因此镜像会从用户的持久存储中删除它们。但这可能需要很长时间。要更快地删除共享数据的本地副本,可以调用persistentContainer.purgeObjectsAndRecordsInZone。
现在,对于我不明白的问题:您所说的“将CKShare深度复制回私有区域”是什么意思?所有者的私有数据库从未被修改过(除了更新CKShare记录中的用户状态,或者--当为最后一个用户停止共享时--删除CKShare记录)。因此,不需要复制CKShare记录。用户的私有数据库都没有被修改。
对于我来说,“深拷贝”返回私有数据库的唯一情况是,即使在共享停止之后,共享用户仍然希望保留共享数据。如果要这样做,必须在所有共享对象可用时立即复制它们,即在将它们从iCloud共享数据库镜像到本地持久存储时立即进行复制。您可以使用.NSPersistentStoreRemoteChange通知来进行复制。然后,purgeObjectsAndRecordsInZone只删除原件,而不删除副本。
编辑:
让我们举一个例子:
在这里名为" owner“的用户在CoreData持久存储中有一些所有者记录,该存储被镜像到所有者的私有数据库的iCloud。在安装过程中,iOS在所有者的私有数据库中创建一个新的区域"com.apple.coredata.cloudkit.zone“。
首先假设没有共享记录。
然后,iOS将更新登录到同一个iCloud帐户的所有设备的持久存储:
本地更改在所有者的私有数据库中导出到此区域,而iCloud更改则导入到所有者的持久存储中。
现在假设所有者邀请另一个名为“参与者”的用户共享所有者的记录层次结构或所有者区域。
然后,在所有者的私有数据库中创建一个CKShare记录,该数据库指定共享细节,即whome共享的内容。
参与者拥有相同的应用程序,在参与者的持久存储中有一些参与者的记录,这些记录反映在参与者的私有数据库中。在安装过程中,iOS在参与者的私有数据库中创建一个新的区域"com.apple.coredata.cloudkit.zone“。
当参与者接受所有者的共享数据邀请时,iOS将所有者的共享数据映射到参与者的共享数据库。“映射”意味着所有者在所有者私有数据库中的com.apple.coredata.cloudkit.zone区域中的数据现在出现在参与者的共享数据库中的一个新区域"com.apple.coredata.cloudkit.zone“中。与共享数据一起,所有者私有数据库的CKShare记录也映射到参与者的共享数据库。
iOS现在将此区域镜像到参与者的持久存储区。
对于所有者来说,除了CKShare记录什么都没有改变。
当所有者或参与者停止共享时,所有者的私有数据库中的所有者数据的映射将终止,即所有者的共享数据不再出现在参与者的共享数据库中。
因为它们是为参与者(但不是为所有者)删除的,所以这反映了参与者的持久存储,共享记录在参与者的持久存储中被删除。然而,这需要一段时间。为了立即删除共享数据,可以在共享终止时使用persistentContainer.purgeObjectsAndRecordsInZone。
我希望这澄清了情况!
https://stackoverflow.com/questions/71584263
复制相似问题