0

I'm building an app which allows users to upload / download info from a common store. I thought cloudKit storage would be ideal for this.

I'd like for users to be able to search records in the store by a KeyWord field, then download the entire record when they select one.

In SQL terms this would be like:

SELECT id,KeyWords from myDB WHERE KeyWords LIKE %searchstring%

Followed by:

SELECT * FROM myDB WHERE id = selectedID

I have been using this code pattern to retrieve records from cloudKit storage:

var publicDatabase: CKDatabase?
let container = CKContainer.defaultContainer()

override func viewDidLoad() {
    super.viewDidLoad()
    publicDatabase = container.publicCloudDatabase
}

func performQuery(){
    let predicate = NSPredicate(value: true)
    let query = CKQuery(recordType: "Library", predicate: predicate)
    publicDatabase?.performQuery(query, inZoneWithID: nil,
        completionHandler: ({results, error in

        ...
        [code to handle results / error here]
        ...
    })
}

but this returns all the content of each record which is a lot of unnecessary info.

I'd like to only fetch a single field from the cloudkit records.

Is there an easy way to do this and does anyone have a code snippet?

CKFetchRecordsOperation allows downloading of restricted columns but requires that you know the ids of the records to download.

2 Answers 2

1

For this you can use the desiredKeys property on a CKQueryOperation. For more information see: desiredkeys documentation

Sign up to request clarification or add additional context in comments.

1 Comment

thanks for the advice. I managed to cobble something together and have posted an answer. If you wouldn't mind casting your eye over it it would be appreciated.
0

OK Got something working. This may well be hacky but I put it up for info for anyone else in the same situation...

let predicate = NSPredicate(value: true) // returns all - replace with whatever condition you want
let query = CKQuery(recordType: "Library", predicate: predicate) // create a query using the predicate
var operation = CKQueryOperation(query: query) // create an operation using the query
operation.desiredKeys = ["KeyWords"] // Array of whatever 'columns' you want to return
// operation.resultsLimit = 15 // optional limit on records

// Define a closure for what to do for each returned record
operation.recordFetchedBlock = { [weak self] (record:CKRecord!) in

    // Do whatever you want with each returned record  
    println(record.objectForKey("KeyWords"))

}

// Define a closure for when the operation is complete
operation.queryCompletionBlock = { [weak self] (cursor:CKQueryCursor!, error:NSError!) in

        if cursor != nil {
            // returns the point where the operation left off if you want t retrieve the rest of the records
        }

        dispatch_async(dispatch_get_main_queue(), { () -> Void in

            // Do what you want when process complete
            self!.tableView.reloadData()
            if error != nil {
                println("there was an error")
            }
        })
    }

self.publicDatabase!.addOperation(operation) // Perform the operation on given database

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.