CKQuery with NSPredicate fails when using "CONTAINS" operator

823 views Asked by At

According to Apples Class Reference CKQuery, the operator CONTAINS is one of the supported operators. However, that doesn't seem to work. I have a RecordType called myRecord, and a record with field name name type String. I try to fetch the record with two different predicates, one with "==" operator, and one with CONTAINS operator.

func getRecords() {
    let name = "John"
    let Predicate1 = NSPredicate(format: "name == %@",name)
    let Predicate2 = NSPredicate(format: "name CONTAINS %@",name)

    let sort = NSSortDescriptor(key: "Date", ascending: false)
    let query = CKQuery(recordType: "myRecord", predicate: Predicate1)
    // let query = CKQuery(recordType: "myRecord", predicate: Predicate2)
    query.sortDescriptors = [sort]

    let operation = CKQueryOperation(query: query)
    operation.desiredKeys = ["name", "Date"]

    operation.recordFetchedBlock = { (record) in
        print(record["name"])

        operation.queryCompletionBlock = { [unowned self] (cursor, error) in
            dispatch_async(dispatch_get_main_queue()) {
                if error == nil {

                    print ("sucess")
                } else {
                    print("couldn't fetch record error:\(error?.localizedDescription)")

                }
            }

        }

        CKContainer.defaultContainer().publicCloudDatabase.addOperation(operation)
    }

Using Predicate1, output is:

Optional(John)
sucess

Using Predicate2, output is:

couldn't fetch record error:Optional("Field \'name\' has a value type of STRING and cannot be queried using filter type LIST_CONTAINS")

Also using [c] to ignore casings gives a server issue.

How do I use the operator CONTAINS correctly?

EDIT: I have now looked closer at the documentation, and seen that CONTAINS can only be used with SELF. Meaning that all String fields will be used for searching. Isn't there a better way?

1

There are 1 answers

3
Linc On

It's an exception mentioned as below:

With one exception, the CONTAINS operator can be used only to test list membership. The exception is when you use it to perform full-text searches in conjunction with the self key path. The self key path causes the server to look in searchable string-based fields for the specified token string. For example, a predicate string of @"self contains 'blue'" searches for the word “blue” in all fields marked for inclusion in full-text searches. You cannot use the self key path to search in fields whose type is not a string.

So, you can use 'self' instead of '%K' in order to search sub-text of string field.

For the full document written by Apple