iOS: CloudKit perform(query: ) 什么都不做 - 闭包未执行

iOS: CloudKit perform(query: ) does nothing - closure not executed

我正在将 CloudKit 添加到我的应用程序以启用 iCloud 同步。但是我 运行 我的方法有问题,它在私有数据库上使用 perform 方法执行查询。

我的方法运行良好,然后我更改了一些相关方法(只是检查 iCloud 是否可用),突然我的 perform 方法什么也没做。我的意思是 perform(query: ) 闭包中的任何内容都没有被执行。我在第一行有断点,在下一行有其他断点,但从未设法击中它们。

private static func getAppDetailsFromCloud(completion: @escaping (_ appDetails: [CloudAppDetails]?) -> Void) {

        var cloudAppDetails = [CloudAppDetails]()
        let privateDatabase = CKContainer.default().privateCloudDatabase
        let query = CKQuery(recordType: APPID_Type, predicate: NSPredicate(format: "TRUEPREDICATE"))

        privateDatabase.perform(query, inZoneWith: nil) { (records, error) in
            if let error = error {
                print(error)
                completion(nil)
            } else {

                if let records = records {

                    for record in records {
                        let appId = record.object(forKey: APPID_ID_Property) as? Int
                        let isDeleted = record.object(forKey: APPID_ISDELETED_Property) as? Int

                        if let appId = appId, let isDeleted = isDeleted {
                            cloudAppDetails.append(CloudAppDetails(id: appId, isDeleted: isDeleted == 1))
                        }
                    }

                    completion(cloudAppDetails)
                    return

                }
            }
            completion(nil)
        }
    }

我的问题从 privateDatabase.perform 行开始,之后没有命中断点,我的执行转移到调用这个 getAppDetailsFromCloud 的函数。没有错误...

这是我第一次实现 CloudKit,我不知道为什么上面的闭包没有任何反应。

感谢您的帮助。

编辑:忘记提及此方法过去工作正常,我能够从 iCloud 获取记录。我没有对它进行任何编辑,现在它不能像描述的那样工作:/

编辑 2:当我 运行 没有附加调试器的应用程序时,一切都完美无缺。我可以按预期在设备之间同步所有数据。当我尝试调试代码时,我再次没有从 iCloud 获取任何记录。

在此处显示的完成处理程序中,如果没有错误且未找到任何结果,执行将失败并安静地退出。因此,此处可能发生两种情况:查询不是 运行 或查询未找到任何结果。我将按顺序执行以下调查步骤:

  1. 检查您的 .entitlements 文件中的密钥 com.apple.dev.icloud-container-environment。如果此密钥不存在,则 xcode 的构建将利用开发环境。如果设置了这个键,那么从 xcode 构建的将访问这个键指向的环境。 (从 Testflight 或应用商店安装此应用的用户将始终使用生产环境)。
  2. 在 Web 浏览器中打开 cloudkit 仪表板并验证您期望的记录确实存在于步骤 1 指示的环境和您期望的容器中。如果记录不存在,那么您就找到了问题。
  3. 如果记录按预期出现在仪表板中,则将断点放在 .perform 行上。如果查询没有按您预期的那样被调用,那么您需要在调用堆栈中更早地查看...预计谁会调用此函数?
  4. 如果 .perform 按预期调用,则将 else 添加到 if let record 语句。在 else 块中放置一个断点。如果触发,则查询 运行 但未找到任何记录。
  5. 如果在上述步骤之后,您发现完成处理程序完全没有执行,这表明查询格式不正确。使用 cloudkit 仪表板手动尝试 运行 查询并观察结果。

闭包异步执行,通常需要等待几秒钟。

考虑到您不能像调试单个线程那样调试多个线程。当您停留在主线程中时,Bcs 调试器不会在关闭时命中断点。

2019,我在处理 CloudKit 任务时遇到了这个问题。 Thunk 选择的答案对我没有帮助,所以我想我要在这里分享我的魔法。我想到了删除断点并打印 results 的想法。它奏效了。但我仍然需要在闭包内使用断点。好吧,我必须做的是重新启动 Xcode。您知道 iOS 开发中的演练,如果出现问题,请重新启动 Xcode,重新连接设备,等等。