我正在开发一个应用程序,它通过NSPersistentCloudKitContainer在iOS 15中使用新的共享支持。我看不到一种方法来告诉Core Data一个对象或一组对象不再共享。
例如,如果我创建了一组对象,然后调用share(_:to:completion:),则这些对象将正确共享,并如预期的那样移动到一个新的自定义CKRecordZone。
现在,如果用户停止使用UICloudSharingController共享对象,则核心数据创建的CKShare将从CloudKit中正确删除,但对象仍在自定义区域中,并且核心数据仍具有与这些对象关联的原始CKShare。因此,当我调用fetchShares(matching:)时,我仍然得到CKShare,但当然,它不再有效。在过去,使用我自己的代码,我会使用UISharingController的委托来得到用户停止共享的通知,然后更新我的模型。但是似乎没有一种方法可以告诉Core Data关于这个变化的信息。
通过将应用程序移动到后台然后移动到前台,或者通过停止应用程序并重新启动,强制核心数据获取CloudKit更改不会导致核心数据注意到共享的更改。
有人知道如何告诉Core Data这些对象不再共享了吗?
发布于 2021-10-07 14:53:28
我解决了这个问题,总是检查共享是否确实存在于CloudKit中,而不是依赖于来自fetchShares(matching:)的CKShare的存在。我从fetchShares(matching:)返回的CKShare中获取URL,并调用以下代码:
private func remoteShare(at url: URL) async throws -> CKShare? {
do {
let metadata = try await cloudKitContainer.shareMetadata(for: url)
return metadata.share
} catch let error as CKError {
if error.retryable {
throw RemoteError.retryable
} else if error.userInterventionRequiredError {
throw RemoteError.userInterventionRequired
} else if error.code == .unknownItem {
return nil
} else {
throw RemoteError.remoteFailure
}
} catch {
throw RemoteError.remoteFailure
}
}
}如果我得到unknownItem,这意味着在远程上没有共享,所以对象实际上并不是共享的。
RemoteError是我定制的错误处理程序,我在CKError上有一些扩展来对错误进行分类。
发布于 2021-10-23 15:48:57
此问题的另一个解决方法是创建要共享的对象的副本,然后删除原始对象。它不是很优雅,但它同时也能工作。(希望苹果能在某个时候用更好的解决方案来解决这个问题。)副本将被放置在默认区域中,就像您共享原始副本之前一样。你会得到一个空的共享区,但我在应用启动时运行了一个后台任务来删除所有空的共享区,这样它就不会失控。
我没有尝试过Dharman发布的解决方案,但我想它比查询本地缓存要慢。使用上面的方法,您仍然可以使用演示应用程序中的"isShared“代码。
https://stackoverflow.com/questions/68604023
复制相似问题