Reputation: 733
I am working on a app that is going to require the use of Core Data and I can't help but notice that Core Data has to be put in manually if you use anything but the Master-Detail, Utility or Blank templates in Xcode.
I also noticed that in order for Core Data to work properly, you HAVE to have your app wrapped in a Navigation Controller and Core Data's code in the AppDelegate files.
Anyone know of a way around this or is this the way it is supposed to be?
My App Delegate looks something like this and those three lines seem to be the most important setup for the ManagedObjectContext!
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
UINavigationController *navController = (UINavigationController *)self.window.rootViewController;
FBBetsViewController *controller = (FBBetsViewController *)navController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
Upvotes: 0
Views: 3124
Reputation: 28409
Those templates include some core data setup, but it is far from mandatory. You can use core data from within any project. If you want, you can just take the code from the empty application, and use it in your project.
If you look in the generated code, you will see three "getters" for the three main components used to build the core data stack.
managedObjectModel creates the model, by using the model file from your bundle. Create that easily in Xcode by New-File and selecting the Core Data Data Model.
persistentStoreCoordinator uses the model, and a SQL store.
Finally, managedObjectContext is created by using the persistentStoreCoordinator. Note, you really can build that stack in one method if you want. There is no requirement to have those individual accessors...
You could do something like this...
- (NSManagedObjectContext*)setupCoreDataStack
{
// Load the model description
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"APPNAME" withExtension:@"momd"];
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
// Prepare the persistent store coordinator - needs the model
NSURL *documentsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *storeURL = [applicationDocumentsDirectory URLByAppendingPathComponent:@"APPNAME.sqlite"];
NSError *error = nil;
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
{
// Handle the error !!!!!
// exit the function
return nil;
}
// Create the managed object context. This is what you will really
// use in the rest of your program.
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[moc setPersistentStoreCoordinator:psc];
return moc;
}
And now you have almost the same stack as the others. The only real difference is that the MOC here is using the main queue concurrency type, which is a much better alternative.
If you want to have a much better performance model, insert a parent moc.
Actually, if you are not married to a current cored data strategy, I'd suggest UIManagedDocument.
Upvotes: 3
Reputation: 21912
Core Data does not impose that you use a navigation controller nor that you set it up in the AppDelegate. It's customary to put the setup in the AppDelegate upon startup but really, you can move it wherever you want as long as you make sure it's only initialized once.
Upvotes: 2