Question

I have started using NSCompoundPredicate to combine my predicates, however have a problem.

Here is an example of one predicate:

Aircraft *obj = (Aircraft *)[self.managedObjectContext objectWithID:objID];
if ([predicateAircraft.predicateFormat isEqualToString:@""] || !predicateAircraft) 
    predicateAircraft = [NSPredicate predicateWithFormat:@"aircraft = %@", obj];
else
{
    NSPredicate *newPredicate = [NSPredicate predicateWithFormat:@"aircraft = %@", obj];
    NSPredicate *compoundPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:[NSArray arrayWithObjects:predicateAircraft, newPredicate, nil]];
    predicateAircraft = compoundPredicate;
}

Aircraft is a subclass of NSManagedObject. This predicate works great, I'm just looping through some Aircraft objects, and adding each to the predicate, so if aircraft1 OR aircraft2 OR etc. etc...

I do this for several properties, same code as above, but creating predicates for different relationships etc. Basically, so the user can filter what data they see, such as which aircraft.

Anyway, once I have built a predicate for each of these, I combine them like so:

NSPredicate *predicateFinal = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:predicateAircraft, predicateBatteries, predicatePilot, nil]];

This time, using AND to combine them. However, using this predicate doesn't filter my data at all. They work individually, but not once combined together in that final line. Any ideas why? That's what I need to resolve.

I have a hunch, could it be that it is creating this: aircraft1 OR aircraft2 OR ... AND ... pilot1 OR pilot2 OR...

Normally you would need parentheses around each bit, such as around the aircraft and pilots to separate them, but the compound doesn't do this?

Effectively what I am getting is:

aircraft = aircraftObj1 OR aircraft = aircraftObj2 AND pilot = pilotObj1 OR pilot = pilotObj2

What I need (I think):

(aircraft = aircraftObj1 OR aircraft = aircraftObj2) AND (pilot = pilotObj1 OR pilot = pilotObj2)

Regardless, any ideas? Thanks.

EDIT:

predicateFinal logs as : TRUEPREDICATE. Not much on it, but apparently TRUEPREDICATE: A predicate that always evaluates to TRUE and is a predicate boolean value. God knows why its returning that?! Presumably that returning true is why there is no visual change is fetch results? As when that is returned there is no change, all objects are fetched.

EDIT 2:

Real progress now. I've fixed any problem with battery objects being part of an NSSet to-many relation but doing ANY battery. But it has revealed the next issue (probably the problem all along).

Was it helpful?

Solution 2

Ok to mix "AND" and "OR" in a compound Predicate I did this...

if ([searchCriteria isEqualToString:@"All"]) {
    [parr addObject:[NSPredicate predicateWithFormat:@"aID_Name     like[cd] %@",mySearchBar.text]];
    [parr addObject:[NSPredicate predicateWithFormat:@"aTrackingNum like[cd]         [parr addObject:[NSPredicate predicateWithFormat:@"aRegNum      like[cd] %@",mySearchBar.text]];
    predicate = [NSCompoundPredicate orPredicateWithSubpredicates:parr];
} 

[parr removeAllObjects];
[parr addObject:predicate];
if (aGroups)
    [parr addObject:[NSPredicate predicateWithFormat:@"SUBQUERY(self.group, $x, $x.gID_Key IN %@).@count > 0",[aGroups valueForKey:@"gID_Key"]]];

predicate = [NSCompoundPredicate andPredicateWithSubpredicates:parr];
NSLog(@"%@",predicate);

OTHER TIPS

Turns out, the NSCompoundPredicate was returning TRUEPREDICATE because the first sub predicate in my compound was nil. (Simple eh? Doh!) So if the first sub predicate is nil, it doesn't matter if any others are not nil, it will stop there and return TRUEPREDICATE and not filter your fetch.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top