Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Point of using NSPersistentStoreCoordinator?

Tags:

ios

core-data

In the Core Data lecture from Stanford 193P iPhone course on iTunes, the instructor coded up a sample project with Core Data without using NSPersistentStoreCoordinator and loading it with a NSManagedObjectModel. But in looking at other code samples and the Big Nerd Ranch book on iPhone development, they are creating a NSManagedObjectModel and PersistentStoreCoordinator and setting up the NSManagedObjectContext that way.

My question is what is the purpose of doing it this way, and what are the pros and cons of both approaches?

like image 759
user1337645 Avatar asked May 23 '12 23:05

user1337645


1 Answers

I followed the same lecture series very closely. This particular example pulls data (Photographers and Photos) from Flickr and loads them into CoreData. It wasn't really necessary to use CoreData in this app since it needs to fetch new data from flickr on every application load, therefore there is no point in saving persistently. The prof was just using the flickr fetching app from the previous demo as a starting point since students were already familiar with it (allowing him to focus on explaining CoreData). However, as rickster mentioned, there are huge benefits to using core data without saving the context to disk.

As Paul explained in the lecture before the demo, a core database can be created (in iOS5) either by:

  1. Clicking "use core data" for an app template when creating a new project.
  2. Using UIManagedDocument

The idea behind the first approach is that Xcode will put a bunch of code in AppDelegate to set up your documents directory/persistent store coordinator/and model. It will then pass the managed object CONTEXT to your initial view controller (which should have an NSManagedObjectContext property in the public API) and from there you can pass the context around like a bottle of beer when you segue to other viewcontrollers. Passing the context around is correct procedure for accessing the core database.

Using UIManagedDocument is very similar, except your AppDelegate is left alone. You create a UIManagedDocument (maybe in your initial view controller) using a URL path from your app's document directory (Note: you have to manually check to see if the file already exits, exists but is not open, or does not exist). Then you can use this document's context in the same way as above.

Another Note: It's a good idea to create a pointer to your context in your AppDelegate so you are able to explicitly save your context (only when it's ready!) when the app crashes or terminates.

The persistent store coordinator is set up automatically for you and you can configure it using it's persistentStoreOptions property (and indeed you will need to in order to save the context persistently), or by subclassing UIManagedDocument and overriding desired methods.

Read the overview in UIManagedDocument documentation http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIManagedDocument_Class/Reference/Reference.html

Both methods work the same way and provide you with the same control and access. With UIManagedDocuments you can create multiple databases in multiple sqlite files, you can also wait to create / set up the database until it's needed. The "use core data" option provides you with a single core database which it sets up on application load, allows you to centralize CoreData stuff around AppDelegate, saves coding time and is good for a fast-track app. I like UIManagedDocument.

If you started you app without the core data option checked and would like to add it to AppDelegate, just create a new project with core data checked and copy all the code to your AppDelegate (should just be 3 properties and their accessors as well as a convenience method to access the documents directory). You will need to point in to your initial view controller, model, etc..

UPDATE: Just wanted to add one other convenience. If your managed object context is stored in your appDelegate, you can access it anywhere in your app just by using

NSManagedObjectContext* context = [[(AppDelegate*) [UIApplication sharedApplication] delegate] myManagedObjectContext];

this negates having to pass it around.

For any CoreData app, if you make any changes to your model, MAKE SURE TO MANUALLY DELETE THE APP IN THE SIMULATOR before building again. Otherwise you will get an error on the next build since it will use the old file.

like image 182
Patrick Borkowicz Avatar answered Oct 13 '22 22:10

Patrick Borkowicz