Documentation Archive

Developer

Core Data Programming Guide

Integrating Core Data and Storyboards

Core Data integrates well with the Xcode Storyboards feature, which you use to build your UI. This integration allows you to take advantage of the dependency injection pattern. Dependency injection is an inversion of control; it allows the caller of a framework to control the flow by passing references into the called object. Dependency injection is one of the preferred patterns to be used with Cocoa development and specifically with iOS Cocoa development.

Integrating Core Data with a Storyboard Segue

A complex integration point for Core Data and storyboards is the transition between a table view displaying numerous data objects and a child view controller that presents the details of one of those items. Without using a storyboard, you accomplish this by overriding the UITableViewDelegate method tableView:didSelectRowAtIndexPath:. However, with a storyboard, this method should not be used, and the transition should be handled within the prepareForSegue:sender: method.

To demonstrate how you can integrate Core Data with a storyboard segue, consider the following example, which shows a primary view controller that is a table view with a list of employees. When one of those employees in that list is selected, you will want to present a detail view of that employee. It is assumed that the view controller within the segue has a property to receive the selected NSManagedObject.

Objective-C

  1. @interface DetailViewController : UIViewController
  2. @property (weak) AAAEmployeeMO *employee;
  3. @end

Swift

  1. class DetailViewController: UIViewController {
  2. weak var employee: EmployeeMO?
  3. }

Next you implement the prepareForSegue:sender: method in the primary view controller to pass the appropriate NSManagedObject instance during the segue:

Objective-C

  1. #define CellDetailIdentifier @"CellDetailIdentifier"
  2. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
  3. {
  4. id destination = [segue destinationViewController];
  5. if ([[segue identifier] isEqualToString:CellDetailIdentifier]) {
  6. NSIndexPath *indexPath = [[self tableView] indexPathForSelectedRow];
  7. id selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
  8. [destination setEmployee:selectedObject];
  9. return;
  10. }
  11. }

Swift

  1. let CellDetailIdentifier = "CellDetailIdentifier"
  2. override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
  3. switch segue.identifier! {
  4. case CellDetailIdentifier:
  5. let destination = segue.destinationViewController as! DetailViewController
  6. let indexPath = tableView.indexPathForSelectedRow!
  7. let selectedObject = fetchedResultsController.objectAtIndexPath(indexPath) as! EmployeeMO
  8. destination.employee = selectedObject
  9. default:
  10. print("Unknown segue: \(segue.identifier)")
  11. }
  12. }

After the segue identifier (which is required to be unique per segue in a storyboard) is retrieved from the segue, you can safely assume what type of class the destination view controller is and pass a reference to the selected Employee instance to the destination view controller. The destination view controller will then have the reference available to it during the loading portion of its life cycle and display the data associated with it. This is dependency injection in that the parent view controller is controlling the flow of the application by deciding which Employee instance to hand off to the destination view controller.