ios - CKQueryOperation queryCompletionBlock 未调用
问题描述
我正在使用CKQueryOperation
显然对我的大多数用户都适用的。但是,对于其中一些人来说,它不起作用。问题是queryCompletionBlock
没有被调用。
分析用户日志我可以看到它对大多数用户都有效,但对其中一些用户不起作用。它在所有类型的 iPhone 型号中都失败了。但 iOS 在故障设备上始终是 iOS 14.2。不幸的是,我无法在我的设备上重现该问题,因此无法对其进行调试。
我已经检查过该问题与互联网连接类型(wifi 或数据)无关
任何的想法?
这是代码
func fetchTeams(_ success: @escaping (_ result: [CKRecord]?) -> Void,
failure: @escaping (_ error: NSError) -> Void) {
bfprint("fetchTeams starts")
let type = RecordType.Team
let predicate = NSPredicate(format: "TRUEPREDICATE")
let query = CKQuery(recordType: type.rawValue, predicate: predicate)
let operation = CKQueryOperation(query: query)
allTeamsRecords = []
executeQueryOperation(operation,
success: success,
failure: failure)
}
private func executeQueryOperation(_ queryOperation: CKQueryOperation,
success: @escaping (_ result: [CKRecord]?) -> Void,
failure: @escaping (_ error: NSError) -> Void) {
bfprint("executeQueryOperation starts")
let configuration = CKOperation.Configuration()
configuration.qualityOfService = .userInitiated
queryOperation.configuration = configuration
queryOperation.queuePriority = .veryHigh
queryOperation.recordFetchedBlock = { [weak self] (record) in
guard let strongSelf = self else {
bfprint("CloudKitDataProvider was deallocated before we got all team records")
return
}
strongSelf.allTeamsRecords.append(record)
}
queryOperation.queryCompletionBlock = { [weak self] (cursor, error) in
bfprint("fetch teams operation completion block called")
if let cursor = cursor {
bfprint("We got a new cursor fetching teams")
let newOperation = CKQueryOperation(cursor: cursor)
guard let strongSelf = self else {
bfprint("CloudKitDataProvider was deallocated before we got all team records")
return
}
strongSelf.executeQueryOperation(newOperation,
success: success,
failure: failure)
}
else if let error = error {
DispatchQueue.main.async(execute: {
failure(error as NSError)
bfprint("Cloud Query Error - Fetching Teams): \(error)")
})
}
else {
DispatchQueue.main.async(execute: {
bfprint("Get teams finished successfully")
guard let strongSelf = self else {
bfprint("CloudKitDataProvider was deallocated before we execute success closure")
return
}
success(strongSelf.allTeamsRecords)
})
}
}
Self.publicDB.add(queryOperation)
bfprint("query added to database")
}
解决方案
我不知道你的情况有什么特别的问题,但我可能会提供一些关于 CloudKit 的一般指导,因为我多年来一直在使用它。CloudKit 确实可靠,但也有点不可靠。:)
以下是一些提示:
- 内置机制以反复检查您是否拥有最新数据。
- 后台通知并不总是出现。有办法获取可能丢失的数据。
- 开发和生产的行为略有不同,因为开发似乎总体上不太可靠。
- CloudKit 仪表板需要不时刷新(就像您的网络浏览器中的整个页面一样),因为即使使用界面中的重新加载和查询按钮,显示的状态也会变得陈旧。
因此,在您的情况下,您可能有办法反复尝试,CKQueryOperation
以便在 CloudKit 出现问题时重新尝试。维护与 CloudKit 同步的本地缓存是我发现确保数据准确的最佳方式。
推荐阅读
- docker - ML docker 容器本地设置完成。现在如何使用 Kubernetes 在共享云平台上进行部署?
- http - 状态 302 - 错误文档移动(HTTP 高级)
- c++ - 关于匿名命名空间和内部链接的标准是什么?
- laravel - Laravel - 如何将外键值显示为视图刀片的标题
- oracle - 带游标的plsql过程
- javascript - 删除重定向 onclick
- python - 如何从 ipynb 文件运行另一个 ipynb 文件?
- c# - Asp.net Core 获取 Bearer error="invalid_token", error_description="签名无效"
- python - 如何使用 groupby 或 resample 对每小时数据进行下采样,以根据 python 中的年日小时索引对数据进行分组?
- rabbitmq - 组件崩溃时 RabbitMQ 崩溃