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 раз, могут быть проблематичными. Если вы делаете выше, вы должны быть в порядке. Некоторым людям нравится писать / вызывать блок курсора как его собственную функцию. Это тоже работает, но это не обязательно.

Другие вопросы по тегам