Search code examples
iosswiftcloudkit

CloudKit private database returns first 100 CKRecords


i am facing this kind of problem working with CloudKit. Trying to fetch all data from "Data" record. Result is limited by 100. How to get all data? Please, thank for any advice.

func getAllDataFromCloudKit(){
    let predicate = NSPredicate(value: true)
    let container = CKContainer.defaultContainer()
    let privateDatabase = container.privateCloudDatabase
    let query = CKQuery(recordType: "Data", predicate: predicate)

    privateDatabase.performQuery(query, inZoneWithID: nil) { results, error in
        if error != nil {
            print(error)
        }
        else {
            for result in results! {
                // return only 100 first 
            }
        }
    }
}

P.S. i found one similar question, still not clear or answer is too old and does not work with the new Swift version

EDIT: See my final solution how to get all data from private database below:


Solution

  • Ok, i found a solution. See below:

    func loadDataFromCloudKit() {
        var results: [AnyObject] = []
        let cloudContainer = CKContainer.defaultContainer()
        let privateDatabase = cloudContainer.privateCloudDatabase
    
        let predicate = NSPredicate(value: true)
        let query = CKQuery(recordType: "Data", predicate: predicate)
        query.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
    
        let queryOperation = CKQueryOperation(query: query)
        queryOperation.desiredKeys = ["id","name"]
        queryOperation.queuePriority = .VeryHigh
        // Max limit is still 100
        queryOperation.resultsLimit = 100
    
        queryOperation.recordFetchedBlock = { (record:CKRecord!) -> Void in
            results.append(record)
        }
    
        queryOperation.queryCompletionBlock = { (cursor, error) in
            dispatch_async(dispatch_get_main_queue()) {
                if (error != nil) {
                    print("Failed to get data from iCloud - \(error!.localizedDescription)")
                } else {
                    print("Successfully retrieve the data form iCloud")
    
                }
            }
            // see cursor here, if it is nil than you have no more records
            // if it has a value than you have more records to get
            if cursor != nil {
                print("there is more data to fetch")
                let newOperation = CKQueryOperation(cursor: cursor!)
                newOperation.recordFetchedBlock = { (record:CKRecord!) -> Void in
                    results.append(record)
                }
    
                newOperation.queryCompletionBlock = queryOperation.queryCompletionBlock
                privateDatabase.addOperation(newOperation)
            } else {
                // gets more then 100
                print(results.count)
            }
        }
        privateDatabase.addOperation(queryOperation)
    }