Combining 'AND' and 'OR' Condition in NSPredicate Combining 'AND' and 'OR' Condition in NSPredicate ios ios

Combining 'AND' and 'OR' Condition in NSPredicate


Addition to @Stuart's answer, you can use NSCompoundPredicate for your OR & AND operations like this.

Obj-C - OR

// OR Condition //NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"X == 1"];NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"X == 2"];NSPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:@[predicate1, predicate2]];

Obj-C - AND

NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"X == 1"];NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"X == 2"];NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[predicate1, predicate2]];

Swift - OR

let predicate1:NSPredicate = NSPredicate(format: "X == 1")let predicate2:NSPredicate = NSPredicate(format: "Y == 2")let predicate:NSPredicate  = NSCompoundPredicate(orPredicateWithSubpredicates: [predicate1,predicate2] )

Swift - AND

let predicate1:NSPredicate = NSPredicate(format: "X == 1")let predicate2:NSPredicate = NSPredicate(format: "Y == 2")let predicate:NSPredicate  = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate1,predicate2] )

Swift 3 - OR

    let predicate1 = NSPredicate(format: "X == 1")    let predicate2 = NSPredicate(format: "Y == 2")    let predicateCompound = NSCompoundPredicate.init(type: .or, subpredicates: [predicate1,predicate2])

Swift 3 - AND

    let predicate1 = NSPredicate(format: "X == 1")    let predicate2 = NSPredicate(format: "Y == 2")    let predicateCompound = NSCompoundPredicate.init(type: .and, subpredicates: [predicate1,predicate2])


I'll do the following using a SUBQUERY.

[NSPredicate predicateWithFormat@"(name == %@) AND (SUBQUERY(subs, $x, $x.numbervalue == %@ or $x.numbervalue == %@).@count > 0)", @"aname", value1, value2];

Try it and let me know.

Another solution could be to grab the whole collection subs and then filter the retrieved set with a predicate to check if elements match for value1 or value2.

Hope it helps.

Edit

If you follow Eimantas suggestion make to sure to create the right array:

NSNumber valueA = [NSNumber numberWithInt:20];NSNumber valueB = [NSNumber numberWithInt:90];NSArray *arr = [NSArray arrayWithObjects:valueA, valueB, nil];


For Swift, this is how you can do it:

SWIFT 4.x - AND

        let p0 = NSPredicate(format: "X == 1")        let p1 = NSPredicate(format: "Y == 2")        fetchRequest.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [p0, p1])

SWIFT 4.x - OR

        let p0 = NSPredicate(format: "X == 1")        let p1 = NSPredicate(format: "Y == 2")        fetchRequest.predicate = NSCompoundPredicate(orPredicateWithSubpredicates: [p0, p1])

SWIFT 4.x - NOT

        let p0 = NSPredicate(format: "X == 1")        let p1 = NSPredicate(format: "Y == 2")        fetchRequest.predicate = NSCompoundPredicate(notPredicateWithSubpredicates: [p0, p1])

Example

This is an example from one of my codes, where I look for uid and sync:

        let p0 = NSPredicate(format: self.uid + " = '" + uid + "'")        let p1 = NSPredicate(format: self.sync + " = %@", NSNumber(value: true as Bool))        fetchRequest.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [p0, p1])