title: Fetching entities with relations in Core Data
body: <p>I have 2 entities in my Core Data database <code>Person</code> and <code>Photo</code> a <code>Person</code> has a <code>To-Many</code> relationship with <code>Photo</code> and <code>Photo</code> has a reverse relationship with <code>Person</code> <code>(Person&lt;--&gt;&gt;Photo)</code>. I load some initial data for my app off a .plist in the following manner:</p>
  
  <pre><code>-(void)populateDataStorage{
  
      NSString *path = [[NSBundle mainBundle] pathForResource:@"FakeData" ofType:@"plist"];
  
      if(path){
          NSArray *plistData = [[NSArray alloc] initWithContentsOfFile:path];
          NSEnumerator *enumerator = [plistData objectEnumerator];
  
          NSArray *personResults;
  
          Photo *photo;
          Person *person;
  
          id currItem = [enumerator nextObject];
  
          while (currItem != nil) {
              photo = (Photo *)[NSEntityDescription insertNewObjectForEntityForName:@"Photo" inManagedObjectContext:[flickrFetcher managedObjectContext]];
  
              photo.name = [currItem objectForKey:@"name"];
              photo.path = [currItem objectForKey:@"path"];
  
              NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@", [currItem objectForKey:@"user"]];
  
              personResults = [flickrFetcher fetchManagedObjectsForEntity:@"Person" withPredicate:predicate];
  
              if ([personResults count] &gt; 0) {
                  person = [personResults objectAtIndex:0];
              } 
              else {
                  person = (Person *)[NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:[flickrFetcher managedObjectContext]];
                  person.name = [currItem objectForKey:@"user"];
              }
  
              photo.person = person;
              [person addPhotosObject:photo];
  
              NSLog(@"Photo %@ added for user %@", photo.name, person.name);
  
              currItem = [enumerator nextObject];
          }
  
          [plistData release];
  
      }
  
  }
  </code></pre>
  
  <p>Everything loads properly. Then I use a <code>NSFetchedResultsController</code> to get the <code>Person</code> and load a <code>UITableView</code> and it all works. When the user clicks on a cell that belongs to a user I have to load another <code>UITableView</code> with the selected Person's Photos, so I do the following in my UITableViewController for my Photo's table view:</p>
  
  <pre><code> - (id)initWithStyle:(UITableViewStyle)style
  {
      self = [super initWithStyle:style];
      if (self) {
          NSPredicate *predicate = [NSPredicate predicateWithFormat:@"person = %@", person];
          self.fetchedResultsController = [[FlickrFetcher sharedInstance] fetchedResultsControllerForEntity:@"Photo" withPredicate:predicate];
      }
      return self;
  }
  </code></pre>
  
  <p>And in my <code>viewDidLoad</code> :</p>
  
  <pre><code>- (void)viewDidLoad
  {
      [super viewDidLoad];
  
      NSError *error = nil;
      [fetchedResultsController performFetch:&amp;error];
  
      for(Photo *photo in person.photos){
          NSLog(@"Photo %@ belongs to %@", photo.name, person.name);
      }
  
      NSLog(@"Photo count %d", [[fetchedResultsController fetchedObjects] count]);
  }
  </code></pre>
  
  <p>The count is giving me 0, i never get the Person's Photos but I know they are properly saved because they all print out for the passed in <code>Person</code>. Any idea what I might be doing wrong?</p>
  
  <p>EDIT</p>
  
  <p>Utility method for getting the <code>NSFetchedResultsController</code> in my <code>FlickrFetcher</code> class:</p>
  
  <pre><code>- (NSFetchedResultsController *)fetchedResultsControllerForEntity:(NSString*)entityName withPredicate:(NSPredicate*)predicate {
      NSFetchedResultsController *fetchedResultsController;
  
      /*
       Set up the fetched results controller.
       */
      // Create the fetch request for the entity.
      NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
      // Edit the entity name as appropriate.
      NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:[self managedObjectContext]];
      [fetchRequest setEntity:entity];
  
      // Set the batch size to a suitable number.
      [fetchRequest setFetchBatchSize:20];
  
      // Edit the sort key as appropriate.
      NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO];
      NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
  
      [fetchRequest setSortDescriptors:sortDescriptors];
  
      // Add a predicate if we're filtering by user name
      if (predicate) {
          [fetchRequest setPredicate:predicate];
      }
  
      // Edit the section name key path and cache name if appropriate.
      // nil for section name key path means "no sections".
      fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self managedObjectContext] sectionNameKeyPath:nil cacheName:@"Root"];
  
      [fetchRequest release];
      [sortDescriptor release];
      [sortDescriptors release];
  
      return [fetchedResultsController autorelease];
  }
  </code></pre>
  
  <p>My own <code>NSFetchedResultsController</code> created in my <code>UITableViewController</code>:</p>
  
  <pre><code>NSFetchRequest *request = [[NSFetchRequest alloc] init];
      NSEntityDescription *entity = [NSEntityDescription entityForName:@"Photo" inManagedObjectContext:[flickFetcher managedObjectContext]];
  
      [request setEntity:entity];
  
      NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
      NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:descriptor, nil];
  
      [request setSortDescriptors:sortDescriptors];
  
      NSPredicate *predicate = [NSPredicate predicateWithFormat:@"person = %@", person];
  
      [request setPredicate:predicate];
  
      fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:[flickFetcher managedObjectContext] sectionNameKeyPath:nil cacheName:@"Root"];
  
      [request release];
      [descriptor release];
      [sortDescriptors release];
  
      NSError *error = nil;
      [fetchedResultsController autorelease];
      [fetchedResultsController performFetch:&amp;error];
  </code></pre>
  
  <p>I don't see the difference.</p>