Swift 4 CloudKit queryCompletionBlock не выполняется
Я следовал нескольким примерам / рассказам CKQueryOperation по проблемам, которые нужно получить из CloudKit. В моей таблице около 370 строк и 8 столбцов. В лучшем случае я могу извлечь только около 60 строк. Параметр resultsLimit, похоже, не помогает.. Мой queryCompletionBlock не выполняется. Иногда я получаю 5 строк, а в другой раз 30+ Ответ из Облака быстрый, сейчас все строки. Это должно быть ошибкой кода новичка!
func getData() {
let predicate = NSPredicate(value: true)
let query = CKQuery(recordType: RemoteFunctions.RemoteRecords.booksDB, predicate: predicate)
let cloudContainer = CKContainer.default()
let privateDatabase = cloudContainer.privateCloudDatabase
let operation = CKQueryOperation(query: query)
operation.queuePriority = .veryHigh
operation.resultsLimit = 20
operation.recordFetchedBlock = { (record: CKRecord) in
self.allRecords.append(record)
print(record)
}
operation.queryCompletionBlock = {[weak self] (cursor: CKQueryCursor?, error: NSError?) in
// There is another batch of records to be fetched
print("completion block called with \(String(describing: cursor))")
if let cursor = cursor {
let newOperation = CKQueryOperation(cursor: cursor)
newOperation.recordFetchedBlock = operation.recordFetchedBlock
newOperation.queryCompletionBlock = operation.queryCompletionBlock
newOperation.resultsLimit = 10
privateDatabase.add(newOperation)
print("more records")
}
// There was an error
else if let error = error {
print("Error:", error)
}
// No error and no cursor means the operation was successful
else {
print("Finished with records:")
}
} as? (CKQueryCursor?, Error?) -> Void
// privateDatabase.add (операция)
}
2 ответа
Вы можете попробовать это...
func getData(withCursor cursor: CKQueryCursor? = nil)
{
let cloudContainer = CKContainer.default()
let privateDatabase = cloudContainer.privateCloudDatabase
let operation: CKQueryOperation
if let cursor = cursor
{
operation = CKQueryOperation(cursor: cursor)
}
else
{
let operation_configuration: CKOperationConfiguration = CKOperationConfiguration()
operation_configuration.isLongLived = true
operation_configuration.qualityOfService = .background
let predicate = NSPredicate(value: true)
let query = CKQuery(recordType: RemoteFunctions.RemoteRecords.booksDB, predicate: predicate)
operation = CKQueryOperation(query: query)
operation.queuePriority = .veryHigh
operation.configuration = operation_configuration
operation.recordFetchedBlock = { (record: CKRecord) in
self.allRecords.append(record)
print(record)
}
operation.queryCompletionBlock = {[weak self] (cursor: CKQueryCursor?, error: NSError?) in
// There is another batch of records to be fetched
print("completion block called with \(String(describing: cursor))")
if let error = error
{
print("Error:", error)
}
else if let cursor = cursor
{
self.getData(withCursor: cursor)
}
else
{
print("Finished with records:")
}
}
}
privateDatabase.add(operation)
}
Это рекурсивная версия вашей функции с использованием нового CKQueryOperation
API.
Кажется, вы теряете ссылку на объект операции, когда появляется курсор.
Удалить as? (CKQueryCursor?, Error?) -> Void
близко к концу. Будьте осторожны, чтобы не удалить предыдущую скобку.
Удалить newOperation.resultsLimit = 10
в вашем блоке курсора.
добавлять operation = newOperation
сразу выше privateDatabase.add(newOperation)
Раскомментируйте privateDatabase.add(operation)
Это должно помочь. Большие выборки, когда блок курсора ударил более 3 раз, могут быть проблематичными. Если вы делаете выше, вы должны быть в порядке. Некоторым людям нравится писать / вызывать блок курсора как его собственную функцию. Это тоже работает, но это не обязательно.