Deriving UITableView sections from NSFetchedResultsController using “to many” relationship

My Core Data model looks like this:

article <--->> category

Is it even remotely possible to use NSFetchedResultsController to produce a UITableView that looks something like this?

Category 1
  - Article A
  - Article B
  - Article C
Category 2
  - Article A
  - Article D
  - Article E
  - Article F
Category 3
  - Article B
  - Article C

Specifically, I'm interested in the (edge?) case where each UITableView section has a unique title (eg, "Category 1", "Category 2"), but the same object can exist in multiple sections (eg, Article A exists in both Category 1 and Category 2).

I have scoured Apple's Core Data docs and have spent two days perusing questions here, but alas, no luck even finding out whether this is possible, let alone how to implement it. Thanks for any help or pointers to a previously answered question. I certainly couldn't find it.

Answers


Yes, it's easy, though there are a million ways to do it.

Your view controller should be the "data source" of the UITableView, and returns information about the number of rows there are and then the contents of each individual row.

There is a concept of a "section" in a tableview, you might choose to have one for each category.

For example, you could create an NSFetchedResultsController to find the categories you want to display, and use that to populate the table view sections, and then each category would have an articles many-to-many relationship, to populate the rows in each section.

Something like this should get you started (assuming your category and article entities both contain a title property):

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
   // return the number of categories
    [[self.categoryResultsController fetchedObjects] count];
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
  // return the title of an individual category
    [[self.categoryResultsController.fetchedObjects objectAtIndex:section] valueForKey:@"title"];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
  // return the number of articles in a category
  MyCategory *category = [self.categoryResultsController.fetchedObjects objectAtIndex:section];

  return category.articles.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  // fetch a cached cell object (since every row is the same, we re-use the same object over and over)
    static NSString *identifier = @"ArticleCellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
    }

    // find the category and article, and set the text of the cell
    MyCategory *category = [self.categoryResultsController.fetchedObjects objectAtIndex:indexPath.section];

    cell.textLabel.text = [[category.articles objectAtIndex:indexPath.row] valueForKey:@"title"];

    return cell;
}

You can read the documentation on these methods to figure out how to customise it further.


Need Your Help

subsonic collection

subsonic

I've written this code to generate a collection. I've tried to filter the collection using subsonic.where but its not working. Actually the where clause will change on user input so i cannot add the

Keeping the array of application data in memory ( singleton class )?

ios sqlite singleton

I am using sqlite to store the array of data and I have more than one view controller in my application and my question is Is it right to create a singleton class to control that array of informati...