NSFetchedResultsController

frc-basic-demo

The signatures of the delegate methods reveal the true purpose of the NSFetchedResultsController class. On iOS, the NSFetchedResultsController class was designed to manage the data displayed by a UITableView or a UICollectionView. It tells its delegate exactly which records changed, how to update the user interface, and when to do this.

Creating the Fetch Results Controller

First, create a NSFetchedResultsController property

Make sure to synthesize it

Create the accessor.

NSFetchedResultsController takes:

  • NSFetchRequest, which must set inject a sort descriptor
  • Managed Object Context

In your accessor, you’ve set the fetchResultsController’s delegate to self. This means
it’ll be delegating messages to us and we have to take care of it. Thus, we do so by conforming to that delegate and implementing its methods.

In your class extension, conform to NSFetchedResultsControllerDelegate:

Finally, perform the fetch in your viewDidLoad:

Basic FRC delegate methods

Adding some Data

First, we get the MOC that’s connected to our fetch results controller.
Then, we set inject that MOC into NSEntityDescription’s insertNewObjectForEntityForName method, which returns us an Managed Object “Hero”.

We then set the properties of that Hero object and have the MOC call save.

Finally, let’s have our fetch results controller do a performFetch. We see that it now has objects.

When you add additional data and have your MOC save, it’ll call the FRC’s didChangeObject: method, which in turn inserts data into your table view by calling insertRowsAtIndexPaths:withRowAnimation.

Making the Results show up

Use your fetch controller for data display instead of NSArray in your cellForRowAtIndexPath.

Do the same for numberOfRowsInSection

Adding objects in a loop

We loop through creating a bunch of Managed Objects. We set the properties to milliseconds to give them unique data.
Then after the loop is done, we simply tell the MOC to save.

Once, you save, you’ll see that our FRC will animate all the adding of the newly added objects into our table.

frc-add
Its output is:

As you can see FRC’s delegate methods will and did change content are always wrapped around insertions, deletions, changes, etc.


ADDING GROUP OF PEOPLE

-[ViewController controllerWillChangeContent:]

-[ViewController controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:]
tableView insertRowsAtIndexPaths:withRowAnimation:




-[ViewController controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:]
tableView insertRowsAtIndexPaths:withRowAnimation:

-[ViewController controllerDidChangeContent:]

Deleting Objects

We delete objects by clicking on the delete button in edit mode. In order to get into edit mode, we need to set TRUE for editing on a table row.

Let’s make the table view editable when we click on a row:

When the edit mode is on, let’s use the default delete button style, which is a rectangular red button.

We can also set the string of the button. Instead of the standard Delete, let’s use “Kick!” instead:

frc-delete

output:

— DELETING OBJECT —
-[ViewController controllerWillChangeContent:]

-[ViewController controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:]
tableView deleteRowsAtIndexPaths:withRowAnimation:

-[ViewController controllerDidChangeContent:]

As you can see, the deletion is animated in our table view!

Click and re-click to get in/out of editing mode

When a table is in edit mode, by default, it does not allow you to re-click or re-select rows. However, if you set the property allowsSelectionDuringEditing to YES, then you can.

Let’s say you want the user to be able to go back to non-edit mode by clicking the table again. Look at property isEditing to see if you’re in edit mode. If so, just simply set the tableview back to NO for setEditing.