Objective-C: Hierarchical passing of CoreData in NavigationController

1.1k views Asked by At

I need some guidance with this issue I have. I have a navigational Controller, with the root controller making use of CoreData and an NSFetchController. Now, the root controller works fine. When I click on an item, hierarchically it should display the next UITable associating the values for the row in the previous root controller.

Now, I am not sure what I should pass as a property to the next UITableViewController. Should it be an array, or should I pass the NSFetchedResultsController? THere will be another level in the hierarchy after the second, as a point of note.

Thanks Doron

1

There are 1 answers

7
Alex Reynolds On BEST ANSWER

You have a couple options, at least:

  1. Pass a reference to the managed object controller from parent view controller to child view controller; or,
  2. Make the MOC property available from the app delegate, which is available to any view controller

Some prefer the second option as you may reuse and rearrange view controllers into different hierarchies. By disconnecting the MOC from parent and child controllers, you gain a bit more design flexibility. Also, if your application needs to manage more than one persistent store concurrently, then getting access from one central point to make multiple MOCs reduces code complexity.

Once you have the MOC in its view controller, you can create your fetched results controller in that view controller and apply operations in their own threads.

EDIT

It sounds like you have a one-to-many relationship between Site and Post (i.e. one site entity has many post entities).

Your "Posts" list view controller could include a site managed object, siteID managed object ID, or a siteName string property.

When you push the "Posts" list VC, set its site or siteName property and configure the request predicate accordingly.

For example, your fetch request's predicate should include something like site.name LIKE '%@' in it, e.g.:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Post" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *requestPredicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"(site.name like '%@')", self.site.name]];
[fetchRequest setPredicate:requestPredicate];
// ...

Or you could compare on managed object IDs, which is generally better for unique comparisons:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Post" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *requestPredicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"(site = %@)", self.siteID]];
[fetchRequest setPredicate:requestPredicate];
// ...

In both cases, you have filtered your Core Data store to match all Post entities that have a site name or a site managed object ID equivalent to your criteria.

Once you perform the fetch, these entities generally reside in an NSSet* or NSArray* that you can easily use as a UITableView data store, especially if you are using a fetched results controller.