views:

503

answers:

2

What I want to do is pretty simple. In my UITableViewController, I want to load data from multiple NSFetchedResultControllers (I have multiple entities in my data model) and put data from each one into a different section in the table view. So for example, all the fetched items from the first NSFetchedResultController would go in section 0 in the UITableView, the fetched items from the other one goes into section 1, etc.

The Core Data template project doesn't demonstrate how to do this. Everything (mainly the index paths) is coded without taking sections into account (there are no sections in the default template) and everything is taken from a single NSFetchedResultController. Are there any example projects or documentation that demonstrates doing this?

Thanks

A: 

You can't. An UITableView can have at most one data source. So, you can not have multiple NSFetchedResultController feed your table.

However, you can have one NSFetchedResultController take care of your table sections, if you can arrange your data model and an associated NSPredicate to be used for retrieving the actual data so that the data retrieved are properly sectioned.

If this is not possible because the data you want to retrieve are totally unrelated, then you need multiple tables, each one associated to a different NSFetchedResultController.In this case, you may want to use the grouped style, so that, even though there are multiple tables, all of them are shown as if they were just one sectioned, grouped table.

unforgiven
You can have multiple NSFetchedResultsController feed a table. It just involves a bit of work. Things like total number of rows in is simply rows of controller1 + rows of controller2.
Giao
A `UITableView`'s datasource and a `NSFetchedResultController` are per se unrelated. The datasource can use one (or more) `NSFetchedResultController` to manage its data, but that's up to the datasource. You can not use a `NSFetchedResultController` as a TableView's datasource directly.
MrMage
I apologize. I must admit that it is technically feasible, and even simple enough. However, I would not do it this way to show totally uncorrelated object. But, this is a personal opinion. Moral of the story: never answer a question just after waking, let the brain think enough, at least have breakfast ;-)
unforgiven
+1  A: 

Assume for a moment the following in your header (code below will be slightly sloppy, my apologies):

NSFetchedResultsController *fetchedResultsController1; // first section data
NSFetchedResultsController *fetchedResultsController2; // second section data

Let the table know you want to have 2 sections:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 2; // you wanted 2 sections
}

Give it the section titles:

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    return [NSArray arrayWithObjects:@"First section title", @"Second section title", nil];
}

Let the table know how many rows there are per sections:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (section == 0) {
        return [[fetchedResultsController1 fetchedObjects] count];
    } else if (section == 1) {
        return [[fetchedResultsController2 fetchedObjects] count];
    }

    return 0;
}

Build the cell:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    ... // table cell dequeue or creation, boilerplate stuff

    // customize the cell
    if (indexPath.section == 0) {
        // get the managed object from fetchedResultsController1
        // customize the cell based on the data
    } else if (indexPath.section == 1) {
        // get the managed object from fetchedResultsController2
        // customize the cell based on the data
    }

    return cell;
}
Giao
Thanks for the detailed answer. That part seems fairly straightforward, however there are a 2 other methods that I'm not so sure about (what they do and if they need any changes) : http://pastebin.ca/1805761
macatomy
It kind of depends on what your app does; it's difficult for me to answer without knowing a whole lot more about the app, design, etc. However, you probably have a safe choice in just having those methods send the table view a reloadData message.
Giao
Managed to get this working with a little tinkering :-) Thanks
macatomy