Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Indexed NSFetchedResultsController

How can I index a NSFetchedResultsController so that I can implement an A-Z index on a tableview.

I see in the initializer I can do sectionNameKeyPath but this just places unique objects in their own section.

Here is what I have for my NSFetchedResultsController

    - (NSFetchedResultsController *)fetchedResultsController
{
    if (__fetchedResultsController != nil) {
        return __fetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Customer" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    [fetchRequest setFetchBatchSize:20];

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];

    [fetchRequest setSortDescriptors:sortDescriptors];

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"name" cacheName:@"Customer"];
    aFetchedResultsController.delegate = self;

    self.fetchedResultsController = aFetchedResultsController;

    return __fetchedResultsController;
}  
like image 533
tofortier Avatar asked Dec 10 '22 03:12

tofortier


1 Answers

implement sectionIndexTitlesForTableView: like this:

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    return [self.fetchedResultsController sectionIndexTitles];
}

this will give you those indexes on the right side of the tableView.

If you want your sections to have names like A, B, C, D etc. you have to implement a method that returns the first letter for your object.

something like this:

- (NSString *)firstLetter {
    [self willAccessValueForKey:@"firstLetter"];
    NSString *firstLetter = [[[self name] substringToIndex:1] uppercaseString];
    [self didAccessValueForKey:@"firstLetter"];
    return firstLetter;
}

This goes into the custom subClass of your coredata entity.

Then add a transient attribute named firstLetter to your core data entity and replace the sectionNameKeyPath in the NSFetchedResultsController init with firstLetter

like image 100
Matthias Bauch Avatar answered Dec 29 '22 10:12

Matthias Bauch