Tutorial :Core Data Navigation with Relationship


My Core Data model looks like this:

alt text http://fwdr.org/lg4q

The players relationship of the entity Game is a to many relationship and will hold all the player objects related to that Game entity.

I have a UITableView that looks like this <-- link . The Table View displays all the games, how would I, when selecting a Game show/push another UITableView to display all the players in the players relationship.

I have already attempted this but to no avail, I think I was on the right track but was plagued by to many errors which I was unable to resolve.


Just create another UITableViewController subclass, wrap it into navigation controller and push. Make sure to use NSFetchedResultsController to populate your table views. You should pass Game object to second table view controller in order to build predicate for it.

Some code snippets:

Wrapping view controller into navigation in table view controller's tableView:(UITableView *)tableView didSelectRowAtIndexPath: method.

    TagsViewController *tagsViewController = [[TagsViewController alloc] initWithMode:TagsViewControllerModeSelect]; // You can view plain style, I've just created my initializer      tagsViewController.unit = self.unit; // You can pass the Game here      [self.navigationController pushViewController:tagsViewController animated:YES];      [tagsViewController release];  

Here is fetched results controller lazy initializer

- (NSFetchedResultsController*)fetchedResultsController  {      if(fetchedResultsController != nil)          return fetchedResultsController;        NSEntityDescription* entity = [NSEntityDescription entityForName:@"StudyUnit" inManagedObjectContext:managedObjectContext];        NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init];      [fetchRequest setEntity:entity];        NSString *predicateString = [[DefaultsManager sharedInstance] filterMode] == kFilterModeShowAll ? @"explanation != '' AND show == YES" : @"ANY tag.show == YES AND explanation != '' AND show == YES";       NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString]; // Here goes your predicate to query players for particular game      [fetchRequest setPredicate:predicate];        NSSortDescriptor* sortByWordDescriptor = [[NSSortDescriptor alloc] initWithKey:@"subject" ascending:YES];      NSArray* sortArray = [[NSArray alloc] initWithObjects:sortByWordDescriptor, nil];      [fetchRequest setSortDescriptors:sortArray];        NSFetchedResultsController* controller = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"Hmm"];      controller.delegate = self;      self.fetchedResultsController = controller;        [fetchRequest release];      [sortByWordDescriptor release];      [sortArray release];      [controller release];        return fetchedResultsController;  }  

Then just implement NSFetchedResultsController delegates, send performFetch message and voila!


Assuming your game object is generally NSManagedObject declared in the second controller:

NSManagedObject *game;  

Then you can build predicate something like this:

NSEntityDescription* entity = [NSEntityDescription entityForName:@"Player" inManagedObjectContext:managedObjectContext];  //...  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"game == %@", self.game];  

This is just theoretically, can't test it sorry ^^


In the second tableView since you already have the game object, you really do not need another NSFetchedResultsController. You can get the players directly from the game object that gets injected into the second view controller and using the relationship display the players.

A second NSFetchedResultsController would only be necessary in this situation if you expected the players to change while the user is viewing that second controller. Otherwise just walking the relationship is sufficient and will use less memory/cpu.

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »