views:

44

answers:

2

My Core Data model looks like this:

alt text

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.

+2  A: 

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!

UPD:

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 ^^

Michael
Ah, I see where you're going. I understand the first snippet but with the second snippet with `predicateString ` and `predicate` how do I query for those particular players? Other than that I understand exactly what you are doing, thanks very much!
Joshua
@Joshua: see my update.
Michael
Cheers, almost all done. ;)Just unsure what to do with this code, `tagsViewController.unit = self.unit;` I've changed it to `playerViewController.game = self.unit;` but I am unsure what to replace `self.unit` with.
Joshua
@Joshua: Assuming you have(gonna have) the same mechanism for the Game controller and you are using `NSManagedObject` for entity, then in `didSelectRowAtIndex` you can retrieve selected game object by `playerViewController.game = [fetchedResultsController objectAtIndexPath:indexPath];`
Michael
That worked wonders!! Thanks again!
Joshua
+2  A: 

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.

Marcus S. Zarra
I see what you mean, but I will need the `NSFetchedResultsController` as I will be adding players within the second controller. Thanks anyway
Joshua
You still would not need one because **YOU** (as in the view you are in) are adding them. A `NSFetchedResultsController` is designed to notify **YOU** that something other than **YOU** has changed the data **YOU** are looking at.
Marcus S. Zarra
Please see my further question on this about accessing `NSManagedObject`'s in a relationship without a `NSFetchedResultsController`. http://stackoverflow.com/questions/3457876/getting-nsmanangedobject-from-a-relationship-without-nsfetchedresultscontroller
Joshua
That link is invalid.
Marcus S. Zarra