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:怎么解决