Swift - получить все записи из публичной базы данных Cloudkit - PullRequest
0 голосов
/ 24 ноября 2018

Привет, я пытаюсь получить все записи из моей публичной базы данных в облачном наборе, и в настоящее время существует более 2000 записей.Как я могу получить их все и поместить в массив?Я попробовал эти два метода без успеха.Не могли бы вы мне помочь?

1 Подход

    let predicate = NSPredicate(value: true)
    let query = CKQuery(recordType: "Position", predicate: predicate)
    query.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]

publicDB.perform(query, inZoneWith: nil) { (results, error) -> Void in            

        if error != nil {

            DispatchQueue.main.async(execute: {  () -> Void in
                self.delegate?.errorUpdating(error: error! as NSError)
                return
            })
        } else {
            self.positionArray.removeAll(keepingCapacity: true)

            for record in results! {

                let position = Position(record: record as CKRecord, database: self.publicDB)
                self.positionArray.append(position)

            }
        }

            DispatchQueue.main.async(execute: {  () -> Void in
               /* my elaboration with the complete result */
            })



    }

2 Подход

    let predicate = NSPredicate(value: true)   
    let query = CKQuery(recordType: "Position", predicate: predicate)

    query.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]

    let qop  = CKQueryOperation(query: query)

    qop.resultsLimit = 3000        
    qop.recordFetchedBlock = { (record: CKRecord) in
        let position = Position(record: record, database: self.publicDB)
        self.positionArray.append(position)
        print(self.positionArray.count)
    }

    qop.queryCompletionBlock = { (cursor: CKQueryOperation.Cursor?, error: Error?) in
        DispatchQueue.main.async(execute: {  () -> Void in
        if let cursor = cursor {

            print("entro")
            let newOperation = CKQueryOperation(cursor: cursor)

            newOperation.recordFetchedBlock = qop.recordFetchedBlock
            newOperation.queryCompletionBlock = qop.queryCompletionBlock
            self.publicDB.add(newOperation)
        }

        else if let error = error {
            print("Error:", error)
        }
            // No error and no cursor means the operation was successful
        else {
            print("Finished with records:", self.positionArray)
            if(!all){
                // my elaboration
            }
            else{
                // my elaboration
            }
        }
        })
    }

    self.publicDB.add(qop)

При первом подходе я могу получить максимум 100 записей.При втором подходе я могу получить не более 400 записей.Но мне нужно заполнить мой массив более чем 2000 записями, как достичь результата?

1 Ответ

0 голосов
/ 24 ноября 2018

Действительно, существует ограничение в 400 записей на операцию выборки, поэтому вам нужно проверить CKQueryCursor значение, возвращаемое блоком завершения запроса , и, если оно не nil, начать другую операцию с ним CKQueryOperation(cursor: cursor).

Так что в принципе ваш второй подход верен.Я предполагаю, что ваша проблема возникает из-за проблем с многопоточностью, попробуйте удалить DispatchQueue.main.async(execute: { () -> Void in.

PS Проверьте, как это делается в RxCloudKit (который автоматически обрабатывает большие выборки), он определенно работает для выборки 1000+записи - RecordFetcher.queryCompletionBlock (курсор: CKQueryCursor ?, ошибка: ошибка?)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...