3
votes

I have Cloudkit records with a 'Keywords' field of type 'text'

I can use this pattern to fetch just the Keywords field of ALL records

let predicate = NSPredicate(value: true)
let query = CKQuery(recordType: "Library", predicate: predicate)
var operation = CKQueryOperation(query: query)  
operation.desiredKeys = ["KeyWords"]
operation.recordFetchedBlock = { [weak self] (record:CKRecord!) in
  ...
}
operation.queryCompletionBlock = { [weak self] (cursor:CKQueryCursor!, error:NSError!) in
  ...
}
self.publicDatabase!.addOperation(operation)

I'd like to limit the returned records to those where the KeyWords field matches a search string which I assume means providing a suitable predicate.

The documentation indicates that CONTAINS is only for lists UNLESS you use the self keyword which searches all text fields

However, replacing the predicate declaration with:

let predicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchString)

results in

*** Terminating app due to uncaught exception 'CKException', reason: 'Predicate comparison options are not supported for expression: SELF CONTAINS[c]

and using

let predicate = NSPredicate(format: "SELF CONTAINS %@", searchString)

results in

*** Terminating app due to uncaught exception 'CKException', reason: 'Unexpected expression: SELF CONTAINS

I am sure it is something straightforward but the docs are not complete yet

1

1 Answers

1
votes

You could use this predicate for a token search:

NSPredicate(format: "allTokens TOKENMATCHES[cdl] %@", tokens)

update: This functionality seems to have changed. You can now use:

NSPredicate(format: @"self contains %@", tokens)

or this:

NSPredicate(format: @"self contains 'bob' AND self contains ‘smith’”)

Fro more info see: https://developer.apple.com/documentation/cloudkit/ckquery