CoreData+CloudKit正在将CKShare还原为CoreData存储



我使用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之前将其深度复制回专用区域?

我不确定我是否正确理解你,但我会尝试一个答案:

假设私有数据库中的记录层次结构或区域应由所有者共享
启动共享时,会邀请用户共享数据,并在所有者的专用数据库中初始化CKShare记录
当用户接受邀请时,CKShare记录和共享数据将通过用户的共享数据库对用户进行访问。它们不会复制到共享数据库;共享数据库只是所有者的私有数据库的一个窗口。但是,如果共享数据库由CoreData+CloudKit镜像到共享用户的持久存储,则会为共享数据创建NSManagedObjects

当所有者或用户停止共享时,用户通常不能再访问这些NSManagedObjects。原则上,这也由iCloud镜像处理:共享数据库不再是所有者数据的窗口,即它不再包含CKShare记录和共享数据,因此镜像会将它们从用户的持久存储中删除。但这可能需要很长时间。要更快地删除共享数据的本地副本,可以调用persistentContainer.purgeObjectsAndRecordsInZone

现在谈谈你的问题,我不明白:你说的";将CCD_ 7深度复制回专用区域";?所有者的私有数据库从未被修改过(除了更新CKShare记录中的用户状态,或者当最后一个用户的共享停止时,删除CKShare记录)。因此,不需要将CKShare记录复制回。用户的专用数据库都没有被修改
唯一的情况是;深度复制";当共享用户想要保留共享数据时,即使在共享停止后,回到私有数据库对我来说也是有意义的。如果你想做到这一点,你必须在所有共享对象可用时立即复制它们,即在它们从iCloud共享数据库镜像到本地持久存储时立即复制。您可以使用.NSPersistentStoreRemoteChange通知来进行复制。purgeObjectsAndRecordsInZone将只删除原件,而不删除副本。

编辑:

让我们举一个例子:
一个用户,称为here"所有者";,在CoreData永久存储中有一些所有者记录,该存储镜像到所有者的私有数据库的iCloud。在设置期间,iOS在所有者的私人数据库中创建一个新的区域";com.apple.coredata.cloudkit.zone";。

首先假设没有共享记录
然后iOS将更新登录到同一iCloud帐户的所有设备的永久存储:
本地更改将导出到所有者的私人数据库中的此区域,iCloud更改将导入到所有者的永久存储。

现在假设所有者邀请另一个用户,称为"这里";参与者";,共享所有者的记录层次结构或所有者的区域
然后,在所有者的私有数据库中创建一个CKShare记录,该记录指定共享详细信息,即由谁共享什么。

拥有相同应用程序的参与者在参与者的持久存储中有一些参与者的记录,这些记录被镜像到参与者的私人数据库。在设置期间,iOS在参与者的私人数据库中创建一个新的区域";com.apple.coredata.cloudkit.zone";。

当参与者接受所有者共享数据的邀请时,iOS会将所有者的共享数据映射到参与者的共享数据库"映射";意味着所有者的私有数据库中的com.apple.coredata.cloudkit.zone区域中的所有者的数据现在出现在新区域中的参与者的共享数据库中";com.apple.coredata.cloudkit.zone";。与共享数据一起,所有者的私有数据库的CKShare记录也被映射到参与者的共享数据库
此区域现在由iOS镜像到参与者的持久存储
对于所有者,除了CKShare记录外,没有任何更改。

当所有者或参与者停止共享时,所有者的数据在所有者的私有数据库中的映射终止,即所有者的共享数据不再出现在参与者的共享数据库中
由于它们是为参与者删除的(但不是为所有者删除的),因此会镜像到参与者的持久存储中,共享记录也会在参与者的持久存储器中删除。然而,这需要一段时间。为了立即删除共享数据,可以在共享终止时使用persistentContainer.purgeObjectsAndRecordsInZone

我希望这能澄清情况!

最新更新