我很难管理一个共享的核心数据对象。我希望我做错了什么,这不仅仅是 cloudkit 共享中的一个错误,而且我还用苹果的一个示例应用程序尝试了同样的问题。
这是我正在做的: 当分享一个新对象时,我这样称呼
UICloudSharingController
:
let cloudSharingController = UICloudSharingController {
(controller, completion: @escaping (CKShare?, CKContainer?, Error?) -> Void) in
container.share([myObject], to: nil) { objectIDs, share, container, error in
if let actualShare = share {
myObject.managedObjectContext?.performAndWait {
actualShare[CKShare.SystemFieldKey.title] = myObject.title
}
}
completion(share, container, error)
}
}
cloudSharingController.delegate = self
present(cloudSharingController, animated: true)
这将打开系统共享对话框。例如,我选择“消息”,它会打开带有共享预览的消息应用程序,就好了。现在,当我取消共享时,事情就变得有趣了。这几乎破坏了我的整个应用程序。我不能再共享此对象或任何其他对象。我总是得到一个错误
CKError 0x281611dd0: "Internal Error" (1/5002); "Couldn't encode share PCS data"
所以看起来从那时起有些东西被破坏了。如果我从共享中删除最后一个人,也会发生同样的情况。
我检查了 CloudKit 控制台,据我所知,问题似乎是新创建的区域不再共享。如果我在 cloudkit 控制台中再次启用该区域的共享并重新启动应用程序,它会再次运行并且我可以再次共享。
什么也坏了,如果我检查我的对象是否已经有一个共享并像这样呈现
UICloudSharingController
:
let controller = UICloudSharingController(share: share, container: CKContainer(identifier: myIdentifier))
controller.delegate = self self.present(控制器,动画:真) 它总是有过时的数据,我刚删除的人仍然在那里,我也无法添加任何新参与者。
我真的必须以某种方式弄清楚共享是否没有更多参与者并自己将其从共享区域中删除并在我的私人区域中创建一个深层副本。我很难相信它一定是那么骇人听闻。必须有另一种方法吗? 如果您需要更多关于我的实施的见解,请告诉我。
不幸的是,Apple 的 CloudKit 共享实现不是很好(尽管它在几年前有所改进)。让它“正确”是很耗时的,你可能会被迫编写你自己的 UICloudSharingController 版本来为最终用户提供最佳体验,因为你无法真正自定义它(例如,隐藏“停止共享”或不需要时的“复制链接”按钮)。此外,“共享”术语可能与您的用户期望或理解的不符。
如果你确实使用它,我建议你自己创建 ckShare,然后只使用 UICloudSharingController(share:, container:) 呈现控制器,因为另一种方法第一次对用户来说可能很慢(即似乎什么都没有发生,直到ckShare 最终创建 - 有时可能需要超过 10 秒)。
但根据我的经验,你能做的最好的事情就是咬紧牙关,在不使用 UICloudSharingController 的情况下将你需要的功能构建到你自己的应用程序中。 Apple 的这个项目有一个示例,您可以在使用 ckShare 完成所需的一切后使用 ShareLink。该项目还有一些很好的评论,可以警告您常见的陷阱: https://developer.apple.com/documentation/coredata/sharing_core_data_objects_between_icloud_users
-- 另外请注意,使用电子邮件发送邀请时共享过程很容易失败(最好坚持使用消息或 AirDrop),因为收件人的电子邮件客户端可能不兼容。如果是这样,他们将无法通过点击邀请来接受邀请。他们会收到一些神秘的错误信息。作为解决方法,他们可以将链接复制到兼容的应用程序(例如 Note)中,但到那时他们可能已经删除了该应用程序......