iOS Developer Library

Developer

CoreData Framework Reference NSFetchedResultsControllerDelegate Protocol Reference

Options
Deployment Target:

On This Page
Language:

NSFetchedResultsControllerDelegate

Inheritance


Not Applicable

Conforms To


Not Applicable

Import Statement


Swift

import CoreData

Objective-C

@import CoreData;

Availability


Available in iOS 4.0 and later.

An instance of NSFetchedResultsController uses methods in this protocol to notify its delegate that the controller’s fetch results have been changed due to an add, remove, move, or update operations.

You should consider carefully whether you want to update the table view as each change is made. If a large number of modifications are made simultaneously—for example, if you are reading data from a background thread—it may be computationally expensive to animate all the changes. Rather than responding to changes individually (as illustrated in Typical Use), you could just implement controllerDidChangeContent: (which is sent to the delegate when all pending changes have been processed) to reload the table view.

The fetched results controller reports changes to its section before changes to the fetched objects themselves.

Typical Use

You can use controllerWillChangeContent: and controllerDidChangeContent: to bracket updates to a table view whose content is provided by the fetched results controller as illustrated in the following example:

  • /*
  • Assume self has a property 'tableView' -- as is the case for an instance of a UITableViewController
  • subclass -- and a method configureCell:atIndexPath: which updates the contents of a given cell
  • with information from a managed object at the given index path in the fetched results controller.
  • */
  • - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
  • [self.tableView beginUpdates];
  • }
  • - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
  • atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
  • switch(type) {
  • case NSFetchedResultsChangeInsert:
  • [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
  • withRowAnimation:UITableViewRowAnimationFade];
  • break;
  • case NSFetchedResultsChangeDelete:
  • [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
  • withRowAnimation:UITableViewRowAnimationFade];
  • break;
  • }
  • }
  • - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
  • atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
  • newIndexPath:(NSIndexPath *)newIndexPath {
  • UITableView *tableView = self.tableView;
  • switch(type) {
  • case NSFetchedResultsChangeInsert:
  • [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
  • withRowAnimation:UITableViewRowAnimationFade];
  • break;
  • case NSFetchedResultsChangeDelete:
  • [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
  • withRowAnimation:UITableViewRowAnimationFade];
  • break;
  • case NSFetchedResultsChangeUpdate:
  • [self configureCell:[tableView cellForRowAtIndexPath:indexPath]
  • atIndexPath:indexPath];
  • break;
  • case NSFetchedResultsChangeMove:
  • [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
  • withRowAnimation:UITableViewRowAnimationFade];
  • [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
  • withRowAnimation:UITableViewRowAnimationFade];
  • break;
  • }
  • }
  • - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
  • [self.tableView endUpdates];
  • }

User-Driven Updates

In general, NSFetchedResultsController is designed to respond to changes at the model layer. If you allow a user to reorder table rows, then your implementation of the delegate methods must take this into account.

Typically, if you allow the user to reorder table rows, your model object has an attribute that specifies its index. When the user moves a row, you update this attribute accordingly. This, however, has the side effect of causing the controller to notice the change, and so inform its delegate of the update (using controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:). If you simply use the implementation of this method shown in Typical Use, then the delegate attempts to update the table view. The table view, however, is already in the appropriate state because of the user’s action.

In general, therefore, if you support user-driven updates, you should set a flag if a move is initiated by the user. In the implementation of your delegate methods, if the flag is set, you bypass main method implementations; for example:

  • - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
  • atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
  • newIndexPath:(NSIndexPath *)newIndexPath {
  • if (!changeIsUserDriven) {
  • UITableView *tableView = self.tableView;
  • // Implementation continues...
  • Notifies the receiver that the fetched results controller is about to start processing of one or more changes due to an add, remove, move, or update.

    Declaration

    Swift

    optional func controllerWillChangeContent(_ controller: NSFetchedResultsController)

    Objective-C

    - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller

    Parameters

    controller

    The fetched results controller that sent the message.

    Discussion

    This method is invoked before all invocations of controller:didChangeObject:atIndexPath:forChangeType:newIndexPath: and controller:didChangeSection:atIndex:forChangeType: have been sent for a given change event (such as the controller receiving a NSManagedObjectContextDidSaveNotification notification).

    Import Statement

    Objective-C

    @import CoreData;

    Swift

    import CoreData

    Availability

    Available in iOS 4.0 and later.

  • Notifies the receiver that a fetched object has been changed due to an add, remove, move, or update.

    Declaration

    Swift

    optional func controller(_ controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath newIndexPath: NSIndexPath?)

    Objective-C

    - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath

    Parameters

    controller

    The fetched results controller that sent the message.

    anObject

    The object in controller’s fetched results that changed.

    indexPath

    The index path of the changed object (this value is nil for insertions).

    type

    The type of change. For valid values see NSFetchedResultsChangeType.

    newIndexPath

    The destination path for the object for insertions or moves (this value is nil for a deletion).

    Discussion

    The fetched results controller reports changes to its section before changes to the fetch result objects.

    Changes are reported with the following heuristics:

    • On add and remove operations, only the added/removed object is reported.

      It’s assumed that all objects that come after the affected object are also moved, but these moves are not reported. 

    • A move is reported when the changed attribute on the object is one of the sort descriptors used in the fetch request.

      An update of the object is assumed in this case, but no separate update message is sent to the delegate.

    • An update is reported when an object’s state changes, but the changed attributes aren’t part of the sort keys. 

    Special Considerations

    This method may be invoked many times during an update event (for example, if you are importing data on a background thread and adding them to the context in a batch). You should consider carefully whether you want to update the table view on receipt of each message.

    Import Statement

    Objective-C

    @import CoreData;

    Swift

    import CoreData

    Availability

    Available in iOS 4.0 and later.

  • Notifies the receiver of the addition or removal of a section.

    Declaration

    Swift

    optional func controller(_ controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType)

    Objective-C

    - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type

    Parameters

    controller

    The fetched results controller that sent the message.

    sectionInfo

    The section that changed.

    sectionIndex

    The index of the changed section.

    type

    The type of change (insert or delete). Valid values are NSFetchedResultsChangeInsert and NSFetchedResultsChangeDelete.

    Discussion

    The fetched results controller reports changes to its section before changes to the fetched result objects.

    Special Considerations

    This method may be invoked many times during an update event (for example, if you are importing data on a background thread and adding them to the context in a batch). You should consider carefully whether you want to update the table view on receipt of each message.

    Import Statement

    Objective-C

    @import CoreData;

    Swift

    import CoreData

    Availability

    Available in iOS 4.0 and later.

  • Notifies the receiver that the fetched results controller has completed processing of one or more changes due to an add, remove, move, or update.

    Declaration

    Swift

    optional func controllerDidChangeContent(_ controller: NSFetchedResultsController)

    Objective-C

    - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller

    Parameters

    controller

    The fetched results controller that sent the message.

    Discussion

    This method is invoked after all invocations of controller:didChangeObject:atIndexPath:forChangeType:newIndexPath: and controller:didChangeSection:atIndex:forChangeType: have been sent for a given change event (such as the controller receiving a NSManagedObjectContextDidSaveNotification notification).

    Import Statement

    Objective-C

    @import CoreData;

    Swift

    import CoreData

    Availability

    Available in iOS 4.0 and later.

  • Returns the name for a given section.

    Declaration

    Swift

    optional func controller(_ controller: NSFetchedResultsController, sectionIndexTitleForSectionName sectionName: String?) -> String?

    Objective-C

    - (NSString *)controller:(NSFetchedResultsController *)controller sectionIndexTitleForSectionName:(NSString *)sectionName

    Parameters

    controller

    The fetched results controller that sent the message.

    sectionName

    The default name of the section.

    Return Value

    The string to use as the name for the specified section.

    Discussion

    This method does not enable change tracking. It is only needed if a section index is used.

    If the delegate doesn’t implement this method, the default implementation returns the capitalized first letter of the section name (see sectionIndexTitleForSectionName: in NSFetchedResultsController).

    Import Statement

    Objective-C

    @import CoreData;

    Swift

    import CoreData

    Availability

    Available in iOS 4.0 and later.

  • Specify types of change.

    Declaration

    Swift

    enum NSFetchedResultsChangeType : UInt { case Insert case Delete case Move case Update }

    Objective-C

    enum { NSFetchedResultsChangeInsert = 1, NSFetchedResultsChangeDelete = 2, NSFetchedResultsChangeMove = 3, NSFetchedResultsChangeUpdate = 4 }; typedef NSUInteger NSFetchedResultsChangeType;

    Constants

    • Insert

      NSFetchedResultsChangeInsert

      Specifies that an object was inserted.

      Available in iOS 3.0 and later.

    • Delete

      NSFetchedResultsChangeDelete

      Specifies that an object was deleted.

      Available in iOS 3.0 and later.

    • Move

      NSFetchedResultsChangeMove

      Specifies that an object was moved.

      Available in iOS 3.0 and later.

    • Update

      NSFetchedResultsChangeUpdate

      Specifies that an object was changed.

      Available in iOS 3.0 and later.

    Import Statement

    Objective-C

    @import CoreData;

    Swift

    import CoreData

    Availability

    Available in iOS 4.0 and later.