UICloudSharingController 不适用于带有 CloudKit 的 Core Data

blu*_*Fox 14 core-data ios imessage cloudkit swiftui

今年夏天,Apple 发布了一个信息丰富的示例应用程序,介绍如何使用 SwiftUI 中的 Core Data、CloudKit 和 UICloudSharingController 在 iCloud 用户之间共享对象。

\n

但是,当用于带有 CloudKit 的 Core Data 时,使用 UICloudSharingController 添加更多参与者似乎不起作用。

\n

MRE
\n请参阅上面链接的 Apple 示例应用程序。\n使用其他示例应用程序时也会出现同样的问题,例如来自 RayW 的示例应用程序。\n该问题不会出现在使用纯 CloudKit 的示例中,例如Apple 的这个示例应用程序

\n

再生产

\n
    \n
  1. 创建新共享,
  2. \n
  3. 使用 UICloudSharingController 管理共享,
  4. \n
  5. 与更多人分享,
  6. \n
  7. 使用消息或其他服务共享。第一次尝试成功,后续尝试失败。
  8. \n
\n

期望
\n我们可以使用 UICloudSharingController 通过消息、邮件或其他平台添加新参与者。该链接将在所有设备上正确显示。

\n

现实
\n在 iOS16+ 上,尝试通过消息共享会使用“协作”框架并导致警告:“发生错误。无法开始协作”(参见图 1)。出现控制台警告(见下文)。触发此错误会中断任何进一步的共享 - 现在也无法为 Mail 和其他平台创建链接(参见图 2)。此外,如果第一次尝试成功,则该链接不会在接收设备上正确显示(参见图 3)。

\n

经过进一步测试,UICloudSharingController 在 iOS15 中也失败了 - 它只是关闭工作表,而不是在紧凑型设备上发出警报。显示现有共享时,UICloudSharingController 肯定会出现问题。

\n

控制台日志:
\n当此问题第一次发生时,会出现以下控制台消息:

\n
    \n
  • CoreDataCloudKitShare[3672:1242159] systemSharingUIDidSaveShareBlock 收到错误:<CKError 0x28314d8c0:“服务器记录已更改”\n(14/2004);server message = "客户端机会锁错误更新记录"; op\n= 134D57570A63DF3A;uuid = 8F070F8B-0AC0-4FFE-A52D-154BCBF3196C;容器 ID = \xe2\x80\x9ccontainerID>
  • \n
\n

其中“containerID”是 CKContainer ID,例如 \xe2\x80\x9ciCloud.com.company.samples.CoreDataCloudKitShare\xe2\x80\x9d。随后尝试添加更多人员时不会出现该消息。

\n

问题
\n如何解决这个问题,以便我们可以使用 CloudKit 和 UICloudSharingController 在用户之间共享核心数据记录?

\n

图片

\n

编辑:

\n
    \n
  • 使用 Core Data 和 CloudKit 进行共享的其他示例也存在同样的问题。此外,当问题第一次发生时,控制台会显示警告。帖子经过编辑以反映这一点。
  • \n
  • Apple 开发论坛中也提出了问题
  • \n
  • 反馈已提交至 FB11623246。
  • \n
  • 进一步测试后补充结论
  • \n
  • 2022 年 10 月 24 日:我以为这个问题在 iOS16.0.3 中已得到解决,但它仍然存在。使用 UIViewController 还是 UIViewControllerRepresentable 调用 UICloudSharingController 并不重要。
  • \n
  • 2022 年 11 月 10 日:该问题出现在开发和生产环境中(通过 TestFlight 测试)
  • \n
  • 2022 年 11 月 15 日:在 Ask Apple 办公时间中,这一问题引起了一位 Apple 工程师的注意,他确认这是一种回归。
  • \n
  • 2022 年 11 月 25 日:DTS 已开放。现在已确认这是一个具有高优先级的已知错误。
  • \n
  • 2022 年 12 月 26 日:该错误在 iOS16.2 中仍然存在。尝试使用 SWCollaborationView 作为 iOS16 中管理协作的替代方案。即使在后续共享中,共享工作流程也会继续进行。然而,SWCollaborationView 似乎与 SwiftUI 不兼容(呃)。请参阅相关的SO 问题
  • \n
  • 2023 年 1 月 17 日:SWCollaborationView 被确认与 SwiftUI 不兼容。FB提交于FB11941664,请也提交FB。
  • \n
  • 2023 年 1 月 25 日:不幸的是,该问题在 iOS 16.3 中仍然存在。
  • \n
  • 2023 年 2 月 15 日:不幸的是,该问题在 iOS 16.3.1 中仍然存在。
  • \n
  • 2023 年 3 月 2 日:Apple 表示该问题应在以下配置中得到解决。我还没有测试过这个(也许下周)。如果有人能证实那就太好了。\n
      \n
    • Xcode 14.3 测试版 2 (14E5207e)
    • \n
    • iOS 16.4 测试版 2 (20E5223e)
    • \n
    • iPadOS 16.4 测试版 2 (20E5223e)
    • \n
    • macOS 13.3 测试版 2 (22E5230e)
    • \n
    \n
  • \n
  • 2023 年 3 月 12 日:我测试了上述配置。UICloudSharingController 现在可以按预期工作。但是,尝试将照片添加到用户是具有写入权限的参与者的现有共享中会导致错误。苹果公司已收到通知,正在等待回应。控制台输出:shareObject(_:to:completionHandler:): Failed to share an object: Error Domain=NSCocoaErrorDomain Code=134060 "A Core Data error occurred." UserInfo={NSLocalizedFailureReason=NSPersistentCloudKitContainer does not support sharing objects across persistent stores. Objects must first be assigned to the correct persistent store (private, or shared as the case may be), so that they can be moved in to the correct record zone for sharing.})
  • \n
  • 2023 年 3 月 14 日:我使用 Apple Sample 应用程序的新分支重新测试并确认了上述问题。如果您想重现该问题,以下是我使用的步骤
  • \n
  • 2023 年 4 月 27 日:经过与 Apple 的反复沟通,我成功解决了本文中描述的问题,并构建了一个具有 Core Data 和 CloudKit 共享的工作应用程序。苹果方面也更新了示例应用程序。任务完成。
  • \n
\n

blu*_*Fox 3

截至 2023 年 4 月 27 日和 iOS 16.4,帖子中描述的问题已由 Apple 解决。

在我的 TSI 中与 Apple 反复讨论后,我成功构建了一个具有 Core Data 和 CloudKit 共享功能的应用程序。

Apple 方面更新了示例应用程序,以反映所讨论的问题以及对 UICloudSharingController 所做的更新。使用相同的链接进行检查。

我想说的是,苹果工程师在解决这个问题上非常有帮助,并为我提供了很多技巧。我很感谢他们的帮助。


对于其他人:您可能很难将对象添加到其他用户的 CKShare(即共享持久存储中)。苹果对此的回应让我走上了正轨:

“现在支持用例的方法是将照片与已经绑定到共享的对象(例如共享标签)相关联。这样,Core Data 在保存照片时会将照片分配到正确的记录区域,就像当您从参与者一侧向共享照片添加新标签时所做的那样。引入相册之类的东西可能是合理的,以便用户可以将照片绑定到共享相册。”

另外,如果您计划在共享之间显示相同的对象(例如,可能会显示在多个相册中的单个照片),请不要忘记无法跨共享记录区域建立关系。因此,您不能拥有与多个相册有关系的单张照片。