Starting a Core Data Project
To start a new Core Data project, open Xcode and select File from the menu, New, and then Project. Xcode will present some project template options to get you started (see Figure 13.2).
Figure 13.2 Xcode new project template choices.
The quickest method to start a Core Data project is to select the Master-Detail template. Click Next to specify options for your new project, and then make sure that Use Core Data is selected (see Figure 13.3). This ensures that your project has the Core Data plumbing built in.
Figure 13.3 Xcode new project options.
When Next is clicked, Xcode creates the project template. The project template includes a “master” view controller, which includes a table view populated by an NSFetchedResultsController, a specialized controller that makes pairing Core Data with a table view a snap. The project template includes a “detail” view to display a single data record. In the sample app, the master and detail views have been renamed to fit the project.
Core Data Environment
The project template sets up the Core Data environment for the project in the class that implements the UIApplicationDelegate protocol; in the sample app this is ICFAppDelegate. The project template uses a lazy-loading pattern for each of the properties needed in the Core Data environment, so each is loaded when needed. For more information about the Core Data environment, refer to Chapter 12, “Core Data Primer.”
The process of loading the Core Data environment is kicked off the first time the managed object context is referenced in the ap. The managed object context accessor method will check to see whether the managed object context instance variable has a reference. If not, it will get the persistent store coordinator and instantiate a new managed object context with it, assign the new instance to the instance variable, and return the instance variable.
- (NSManagedObjectContext
*)managedObjectContext {if
(__managedObjectContext
!=nil
) {return
__managedObjectContext
; }NSPersistentStoreCoordinator
*coordinator = [self
persistentStoreCoordinator
];if
(coordinator !=nil
) {__managedObjectContext
= [[NSManagedObjectContext
alloc
]init
]; [__managedObjectContext
setPersistentStoreCoordinator
:coordinator]; }return
__managedObjectContext
; }
The persistent store coordinator is the class that Core Data uses to manage the persistent stores (or files) where the data for the app is stored. To instantiate it, an instance of NSManagedObjectModel is needed so that the persistent store coordinator knows what object model the persistent stores are implementing. The persistent store coordinator also needs a URL for each persistent store to be added; if the file does not exist, Core Data will create it. If the persistent store doesn’t match the managed object model (Core Data uses a hash of the managed object model to uniquely identify it, which is kept for comparison in the persistent store), then the template logic will log an error and abort. In a shipping application, logic would be added to properly handle errors with a migration from the old data model to the new one; in development having the app abort can be a useful reminder when the model changes to retest with a clean installation of the app.
- (NSPersistentStoreCoordinator
*)persistentStoreCoordinator {if
(__persistentStoreCoordinator
!=nil
) {return
__persistentStoreCoordinator
; }NSURL
*storeURL = [[self
applicationDocumentsDirectory
]URLByAppendingPathComponent
:@"MyMovies.sqlite"
];NSError
*error =nil
;__persistentStoreCoordinator
= [[NSPersistentStoreCoordinator
alloc
]initWithManagedObjectModel
:[self
managedObjectModel
]];if
(![__persistentStoreCoordinator
addPersistentStoreWithType
:NSSQLiteStoreType
configuration
:nil
URL
:storeURLoptions
:nil
error
:&error]) {NSLog
(@"Unresolved error %@, %@"
, error, [erroruserInfo
]);abort
(); }return
__persistentStoreCoordinator;
}
The managed object model is loaded from the app’s main bundle. Xcode will give the managed object model the same name as your project.
- (NSManagedObjectModel
*)managedObjectModel {if
(__managedObjectModel
!=nil
) {return
__managedObjectModel
; }NSURL
*modelURL = [[NSBundle
mainBundle
]URLForResource
:@"MyMovies"
withExtension
:@"momd"
];__managedObjectModel
= [[NSManagedObjectModel
alloc
]initWithContentsOfURL
:modelURL];return
__managedObjectModel
; }