未调用 CKQueryOperation queryCompletionBlock
CKQueryOperation queryCompletionBlock not called
我使用的 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 同步的本地缓存是我发现确保数据准确的最佳方法。
我 99% 确定这是一个 iOS 问题。用户更新到 iOS 14.3 后问题消失了
我使用的 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 同步的本地缓存是我发现确保数据准确的最佳方法。
我 99% 确定这是一个 iOS 问题。用户更新到 iOS 14.3 后问题消失了