自 Xcode 13 / iOS15 以来,获取“公共数据库中不允许自定义区域”

Posted

技术标签:

【中文标题】自 Xcode 13 / iOS15 以来,获取“公共数据库中不允许自定义区域”【英文标题】:Getting "Custom zones are not allowed in public DB" since Xcode 13 / iOS15 【发布时间】:2021-12-04 04:48:59 【问题描述】:

第一次在这里发帖,急需帮助。

我在开发使用 CloudKit Public DB 的应用程序时遇到了问题。我对此比较陌生,我可能做错了什么。我已经提炼了这个问题,只使用当您使用 iCloud 应用程序创建新的 Core Data 时出现的模板应用程序,并详细说明了以下步骤。可能是我在做傻事。

这在 ios 14 中有效,但在 iOS 15 和 XCode 13 出现后,它就停止了。我正在使用 SwiftUI。

简而言之,同步到公共数据库仅适用于应用程序的首次运行。停止并重新启动应用程序似乎会引发错误并导致镜像委托失败。

感谢所有帮助/建议。以下步骤重新创建问题:

    使用 ICloud 中的核心数据和主机创建应用程序 - 界面是 SWiftUI

    在项目签名和功能中添加 iCloud 和后台模式

    在新出现的 iCloud 部分启用 Cloudkit 并选择或创建一个容器

    在新出现的背景模式部分启用远程通知

    在 persistence.swift 添加:

导入 CloudKit

    仍在 persistence.swift 中添加以下内容:
guard let description = container.persistentStoreDescriptions.first else

fatalError("Something bad happened")


description.cloudKitContainerOptions?.databaseScope = .public

我在以下行之前添加了这个:

  container.loadPersistentStores(completionHandler:  (storeDescription, error) in

    在模式模型中,突出显示默认配置并在数据模型检查器中检查“使用 cloudkit”是否被选中

    运行应用程序并点击 + 几次以添加一些记录。

    在第 3 步中选择/创建的容器中的公共数据库中检查 Cloudkit Dashboard。您需要在 __recordID 和 __modTime 上创建索引才能查看记录。

您应该会看到大约一分钟后的记录都出现在公共数据库中。 Xcode 的控制台窗口没有报错。

    停止并重新启动应用程序。

    这次单击加号按钮时,记录不会上传到公共数据库,控制台会报告类似以下的错误消息:

CoreData: CloudKit: CoreData+CloudKit: -NSCloudKitMirroringDelegate _finishedRequest:withResult:: Finished request: 9F190C45-7713-4ACE-96DB-867D99FF62ED 结果: 成功: 0 madeChanges: 0 错误:错误域 = NSCocoaErrorDomain 代码 = 134406“请求 '9F190C45-7713-4ACE-96DB-867D99FF62ED' 被中止,因为镜像委托由于错误而从未成功初始化:defaultOwner = >" UserInfo=NSLocalizedFailureReason=Request '9F190C45-7713-4ACE-96DB-867D99FF62ED' 被中止,因为镜像委托由于错误而从未成功初始化:defaultOwner = >

所以基本上:

a) 我是不是在做傻事 要么 b)代码在其他地方工作 - 所以必须是我的设置 要么 c) 这是出乎意料的行为,我将不得不等待 Apple 对其进行排序。

提前感谢您提供的所有帮助。

干杯,

伊恩

【问题讨论】:

什么是名为“容器”的家伙,它是如何设置的? 感谢您回到我身边。创建项目并为目标添加 iCloud 功能,出现 iCloud 面板。它有两个主要部分,服务 - 您可以在其中检查 CloudKit 和容器。如果你还没有容器,点击加号,你会得到一个弹出窗口。然后给它起一个像“com.acme.test1”之类的名字(让它对你自己有用,因为据我所知你不能删除它们)。当你保存它时,它会显示几秒钟,然后变成灰色。您需要登录您的 iCloud 帐户。单击 CloudKit 控制台按钮将在线显示它。 我用过 CloudKit 很多次。一个叫“容器”的人是从哪里来的?它是一个变量,只有你知道它在哪里设置。 这是我在 Persistence.swift 中创建项目时自动生成的,不是我添加的。我给我的项目起的名字是TestCK3。这就是代码的样子: let container: NSPersistentCloudKitContainer init(inMemory: Bool = false) container = NSPersistentCloudKitContainer(name: "TestCK3") if inMemory container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/开发/空") 我对标记有一些疑问 - 请原谅。在模型本身中,我没有更改任何内容,只是使用了默认的 Item 实体。这显然不是我的应用程序代码,你可能会写一篇关于可以改进的东西的论文,但是这个简单的模板设置说明了我遇到的问题。 【参考方案1】:

对于那些偶然发现这一点的人来说,这个问题现在似乎在 iOS 15.1 中得到了解决。我先安装了 Xcode 13.1,但这并没有解决问题,但是当我升级我的测试设备时,它可以工作了。是 iOS 15.1 还是两者的结合,我不能肯定。

后续行动。我仍然不相信这是 100% 正确的。我的代码再次正常工作,然后似乎恶化,然后完全停止工作。我已经能够让它再次运行。它似乎与 Cloudkit 架构相关联。仅模式的初始化似乎是不够的。我很确定它是以前的,因为我会进行初始化,然后手动创建索引以查看我的记录。为了让它再次工作,我必须预先创建索引,因为我收到错误消息说镜像委托由于错误而没有成功初始化 “无效的论点”(12/2015); server message = "字段 'recordName' 未标记为可查询"; 所以 recordID 需要一个可查询的索引,而 modTime 需要可查询和可排序的。我还注意到 Cloudkit Dashboard 中似乎有一个小故障,如果同时为 modTime 添加两个索引,其中一个不会出现。因此,请务必检查后。如果这继续困扰我一个多月,我将添加更新。如果有人发现我犯了新错误,请发表评论并告诉我。

【讨论】:

在 Xcode 13.2 和 iOS 15.1.1 上仍然存在问题。 CloudKit 仪表板也不允许我在 modifiedTimestamp 上添加可排序索引(我只能假设这就是 __modTime 的含义?)。 CloudKit 同步对于生产来说似乎真的很不稳定。 更新:事实证明我可以在经典页面刷新后在 modifiedTimestamp 上添加一个可排序和可查询的索引。所以我在所有 CloudKit 实体上都这样做了,它工作正常,Core Data 正在与 CloudKit 同步。 是的 - 抱歉,刚刚看到您的评论。 __modTime 是 modifiedTimestamp 据我所知,它似乎确实有效。我不知道为什么,但是 Cloudkit 中列的命名已经从 __modTime 到 modifiedTime 来回更改。

以上是关于自 Xcode 13 / iOS15 以来,获取“公共数据库中不允许自定义区域”的主要内容,如果未能解决你的问题,请参考以下文章

自 Xcode 6.3 以来可能出现的新 iBeacon 监控问题

Xcode 13 - 缺少 IOS 15 模拟器?

EmptyView 未在 iOS 15、Xcode 13 中显示

iOS15 UI相关的适配

iOS之深入解析Xcode 13(iOS 15)正式版发布的新特性

苹果手机适配Xcode13打包及IOS15系统