Search code examples
objective-cuitableviewcore-datansfetchedresultscontrolleruitableviewsectionheader

Duplicate rows under section titles with NSFetchedResultsController


I'm so close... but must be missing something.

My local DB has a list of golf courses with various details including among other things, the State, first letter of the state's name (A, C, D, ) etc... The NSFetchedResultsController is grabbing a list of courses and is (or was) working great showing all the states that that had a course I have records for.

At any rate... the section heads seem to be working... but my states are now being duplicated for the number of courses that each given state has.

Code and screen shot below. What am I missing?!? It has to be something so obvious.

enter image description here

-(NSFetchedResultsController *)fetchedResultsController {
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription
                                   entityForName:@"Courses"
                            inManagedObjectContext:_managedObjectContext];

    request.entity = entity;

    request.sortDescriptors = [NSArray arrayWithObject:
                               [NSSortDescriptor
                                sortDescriptorWithKey:@"locState"
                                ascending:YES
                            selector:@selector(caseInsensitiveCompare:)]];


    request.returnsDistinctResults = YES;
    request.fetchBatchSize = 20;

    NSFetchedResultsController *frc = [[NSFetchedResultsController alloc]
                                       initWithFetchRequest:request
                            managedObjectContext:self.managedObjectContext
                                sectionNameKeyPath:@"locStateSectionHead"
                                       cacheName:nil];
    frc.delegate = self;

    NSError *error = nil;
    if (![frc performFetch:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    self.fetchedResultsController = frc;
    return _fetchedResultsController;
}

And then the rest of the tableView setup:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return [[self.fetchedResultsController sections] count];
}

- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {

    if ([[_fetchedResultsController sections] count] > 0) {
        id <NSFetchedResultsSectionInfo> sectionInfo = [[_fetchedResultsController sections] objectAtIndex:section];
        return [sectionInfo numberOfObjects];
    } else {
        return 0;
    }
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo name];
}

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

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
    return [self.fetchedResultsController sectionForSectionIndexTitle:title atIndex:index];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"stateCell"];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
    }

    // Configure the cell...
    Courses *course_info = [_fetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = course_info.locState;

    return cell;
}

Solution

  • Assuming you want your table view to display the states then your NSFetchedResultsController should be fetching the State not the Course. You are getting duplication because you are sorting from courses and you have multiple courses in a state.

    Configure your NSFetchedResultsController to load the State entity then your table view will display properly. From there when a user selects a state you can use the relationship from State to Course to display your next scene.

    You simply have it backwards :)