iOS:CloudKit perform(query:) 啥都不做 - 没有执行闭包

Posted

技术标签:

【中文标题】iOS:CloudKit perform(query:) 啥都不做 - 没有执行闭包【英文标题】:iOS: CloudKit perform(query: ) does nothing - closure not executediOS:CloudKit perform(query:) 什么都不做 - 没有执行闭包 【发布时间】:2018-02-28 19:13:41 【问题描述】:

我正在将 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 获得任何记录。

【问题讨论】:

“我的问题始于 privateDatabase.perform 行”您的问题可能始于该行的正上方。 检查 APPID_Type 是 CloudKit 方案中的有效类型名称。 @Adolfo 是的,我忘了提到在我对其他记录进行更改之前,我设法用这种方法获取了所有记录。 @ElTomato 你到底是什么意思?我之前有这个工作,并没有专门对这个方法进行任何更改。 【参考方案1】:

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

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

【讨论】:

非常感谢您采取的详细步骤。我不知道我的应用程序中发生了什么。当我在没有调试的情况下启动它(相同的代码不能像描述的那样工作)一切正常,我的所有数据都在 iPhone 和 iPad 之间同步。调试仍然是同样的问题 + 我什至设法从 CloudKit 获得了数百万条记录,然后无法使用......我很困惑 另一个更新。我禁用了大部分断点并尝试调试,因为我想测试其他东西,突然我的最后一个断点(我忘了关闭)被击中。这似乎是我的“过度”断点使用以某种方式破坏了 CloudKit……这可能吗?【参考方案2】:

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

考虑到您不能以与单个线程相同的方式调试多个线程。当您停留在主线程中时,Bcs 调试器不会在关闭时遇到断点。

【讨论】:

【参考方案3】:

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

【讨论】:

以上是关于iOS:CloudKit perform(query:) 啥都不做 - 没有执行闭包的主要内容,如果未能解决你的问题,请参考以下文章

ios performselector:withobject:withobject:怎么解决

CloudKit iOS 10 错误:帐户无权访问 CloudKit 帐户

iOS performSelector(参考)

用于网站和 iOS 的 CloudKit

iOS performSelector方法总结

将 iOS 应用从 Cloudkit 开发转移到生产