NSPredicate on nested object / NSSet to filter the result during NSFetchRequest

5.1k views Asked by At

I want a simple predicate that returns me all the groups which have mode = 0 and the mode of the enrollments in the group = 0

To be precise i need a predicate to access the nested object properties. Somehow a predicate like:

[NSPredicate predicateWithFormat:@"mode = 0 AND enrollments.Enrollment.mode = 0"]

the above predicate is wrong and obviously doesn't work.

EDITED:

I have given a go to the following predicate too but been unsuccessful.

[NSPredicate predicateWithFormat:@"mode = 0 AND ALL ( SUBQUERY(enrollments,$varEnrollment,$varEnrollment.mode = 0))"]

I need result which contains all groups that are active (group.mode = 0) AND with all enrollee's that are active (enrolles.mode = 0) but for me this predicate doesn't work.

1

There are 1 answers

14
Martin R On BEST ANSWER

From your question and the comments I guess that you want

[NSPredicate predicateWithFormat:@"mode = 0 AND (ALL enrollments.mode = 0)"]

UPDATE

It seems that the ALL aggregate does not work. It throws

'NSInvalidArgumentException', reason: 'Unsupported predicate (null)'

as @yunas noticed. This has also been noticed previously, e.g.

On the other hand, the ANY aggregate works just fine. So as a WORKAROUND, one can replace ALL with an equivalent ANY expression:

[NSPredicate predicateWithFormat:@"mode = 0 AND NOT(ANY enrollments.mode != 0)"];

And this actually works (I have tested it)!

UPDATE 2

During the discussion it has become clear that yunas wants to display a table with one row for each group with mode=0, and within the table row display all enrollments of that group with mode=0.

First solution (probably the better one): Find all admissible groups first with the method given above. For each row (in cellForRowAtIndexPath:) filter the enrollments for that group and draw the cell.

Second solution: Fetch all enrollments and sort them by group. This requires only one fetch request, but the result is not so suitable as table view data source. The fetch request would look like this:

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Enrollment"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"mode = 0 AND group.mode = 0"];
request.predicate = predicate;
NSSortDescriptor *sort1 = [NSSortDescriptor sortDescriptorWithKey:@"group.name" ascending:YES];
NSSortDescriptor *sort2 = [NSSortDescriptor sortDescriptorWithKey:@"share" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObjects:sort1, sort2, nil];