Search code examples
iosnspredicatecloudkitckquery

Use CONTAINS or ANY in CloudKit predicate with an array of comparison


I tried to use NSCompoundPredicate(orPredicateWithSubpredicates:) with CloudKit NSPredicate but then I read on Apple's documentation that OR comparison predicates aren't supported in CloudKit so I hit a road-block with this.

I have an array of CKReferences that I need to see if a Record-type of Reference list contains those references.

I'm struggling on how to assemble the predicate itself , because I'm trying to avoid nested-queries in the completionBlock.

let's say I have the following array of references:

let refs = [CKReference]() // in my case the array isn't empty

I tried the following but it didn't worked, because somehow it only looks for the first object of the array, and not the whole array.

let predicate = NSPredicate(format: "tableName CONTAINS %@", argumentArray: refs)

Here if I print the predicate it prints:

tableName CONTAINS CKReference: 0x600000229c40; 20B54862-46CC-405F-BAE8-0DC8D3A52F78:(_defaultZone:defaultOwner)>

As you can see, it only looks for the first object in the array.

It may work if I use the ANY operator in the predicate, something like:

let predicate = NSPredicate(format: "ANY { '%@', '%@' } = tableName", args: refs[0], refs[1])

But my problem here is how can I build that predicate, since the refs array is dynamic and I don't know how many objects it may contain , and by that I don't know how to build the predicate args accessing the [0], [1], ... of the refs array.

Do you have any workaround with this? Or a best way to approach this issue?

Thank you.

EDIT

I figure out a way to solve this issue, but I don't know if that's the most efficient one, so I'm still opened to answers and opinions.

Here's my temporary solution:

for (i, reference) in  refs.enumerated() {
    let predicate = NSPredicate(format: "tableName CONTAINS %@", reference)
    // CKQuery
    // CKQueryOperation
    // Database.add(CKQueryOperation)
    if i == refs.count - 1 {
        // UPDATE UI
    }
}

Solution

  • NSMutableArray * tagsReferencesArray = [[NSMutableArray alloc] init];
    
        [tagsReferencesArray addObject:tag100_Reference];
        [tagsReferencesArray addObject:tag300_Reference];
        [tagsReferencesArray addObject:tag200_Reference];
    
    predicate= [NSPredicate predicateWithFormat:@"ANY %@ in field_TagsReferenceList ", tagsReferencesArray];