Question

I have two entities, A and B, and the following relationships:

A -> B - To many

B -> A - To one

In other words: A can have zero or more B and B can have only one A.

I want to use NSFetchedResultsController to show my A entries in a table view, but i want to filter the results by A -> B relationship. To do so, i have a UISegmentedControl, if the user taps the first segment i want to show only the A entries that have at least one relationship with B, and if the second segment is tapped i want to show only the entries with no relationships with B.

I'm using CoreData's NSManagedObject, so my A object has a NSSet property with all B entries in a relationships with A.

This is how i'm instantiating my NSFetchedResultsController:

    NSManagedObjectContext *context = self.managedObjectContext;
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    NSEntityDescription *entity = [NSEntityDescription entityForName:"A" inManagedObjectContext:self.managedObjectContext];

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:descriptorKey ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    [fetchRequest setSortDescriptors:sortDescriptors];
    [fetchRequest setEntity:entity];


    NSFetchedResultsController *controller = [[NSFetchedResultsController alloc]
                                              initWithFetchRequest:fetchRequest
                                              managedObjectContext:context
                                              sectionNameKeyPath:controllerKey
                                              cacheName:nil];

    NSError *error;
    BOOL success = [controller performFetch:&error];

    if (success) {
        return controller;
    }

This code get all A entries, how can i make that filter?

Was it helpful?

Solution

You need to add a predicate to your fetch request:

e.g.

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"B.@count == 0"];
[fetchRequest setPredicate:predicate];

This will filter As that don't have any related B objects.

OTHER TIPS

As @Abizern mentioned in comments, you need to add a NSPredicate to your NSFetchedResultsController. The predicate would be something like:

[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"b == %@", myVarReferenceToB]];

If you only have a unique identifier in B (lets call it identifier) instead of an object reference you could write it as:

[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"b.identifier == %@", myVarReferenceToBIdentifier]];

This will produce your filter.

Every time the user changes the segmented control you will need to re-build the fetch or you will need to keep one NSFetchedResultsController around per segment.

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