Online Book Reader

Home Category

iOS Recipes - Matt Drance [79]

By Root 205 0
store, model, and managed object context, making sure we that support migration between model versions. This code can create unwanted clutter and dependencies in our project if done in the wrong place.

This recipe introduces a basic data model that takes care of the standard initialization nearly every Core Data--based app goes through. You can easily edit or subclass the model class to tailor its behavior to meet your own application’s needs.

The first job of this basic data model is to abstract away the low-level initialization every Core Data--based application needs to perform: it initializes the managed object model, loads a persistent store coordinator, and creates a default managed object context. This class uses a SQLite store by default.


Use a Versioned Model

If you’re working with Core Data, it pays to use a versioned model from day one. If you start with an explicit .mom file then move to a versioned .momd folder, you can end up with stale, conflicting files in your project. This can cause hard-to-track errors during development, especially when using mergedModelFromBundes: to create your model. These headaches might be passed along to your users if you make this transition between version 1.0 and 2.0 of your product. Ship a .momd file from the beginning.

This recipe uses the more explicit -[NSManagedObjectModel initWithContentsOfURL:] precisely because you may end up having more models in your bundle than you thought. The templates that ship with Xcode 4 are built this way, but older projects may not be. Take a look at your projects to make sure you’re ready for a version migration.


The read-only managedObjectModel property is lazily initialized and points to a single model file, which defaults to a .momd with the last component of the app’s bundle identifier as its filename. For example, a bundle identifier of com.pragprog.BasicDataModel results in a model name of BasicDataModel.momd. We can configure the model file’s name and path by editing or overriding ‑modelName and ‑pathToModel, respectively.

BasicDataModel/Shared/PRPBasicDataModel.m

- (NSManagedObjectModel *)managedObjectModel {

if (managedObjectModel == nil) {

NSURL *storeURL = [NSURL fileURLWithPath:[self pathToModel]];

managedObjectModel = [[NSManagedObjectModel alloc]

initWithContentsOfURL:storeURL];

}

return managedObjectModel;

}

BasicDataModel/Shared/PRPBasicDataModel.m

- (NSString *)modelName {

return [[[NSBundle mainBundle] bundleIdentifier] pathExtension];

}

- (NSString *)pathToModel {

NSString *filename = [self modelName];

NSString *localModelPath = [[NSBundle mainBundle] pathForResource:filename

ofType:@"momd"];

NSAssert1(localModelPath, @"Could not find '%@.momd'", filename);

return localModelPath;

}

The read-only persistentStoreCoordinator property is lazily initialized and preconfigured to perform automatic lightweight migration between model versions. This way, if we add new versions of our model with small changes that support lightweight migration, we don’t need to do any additional work.

Keep in mind that migration isn’t always easy. Basic changes to a Core Data model, such as new or renamed attributes, can usually be migrated automatically. However, there are plenty of cases where a model change is too complex to be automigrated. Before making changes to a model you’ve already shipped, read Apple’s Core Data Model Versioning and Data Migration Programming Guide on the iOS Dev Center. And be sure to add a model version in Xcode before making changes. Never edit a model version that’s in the wild!

BasicDataModel/Shared/PRPBasicDataModel.m

NSURL *storeURL = [NSURL fileURLWithPath:[self pathToLocalStore]];

NSPersistentStoreCoordinator *psc;

psc = [[NSPersistentStoreCoordinator alloc]

initWithManagedObjectModel:self.managedObjectModel];

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:

[NSNumber numberWithBool:YES],

NSMigratePersistentStoresAutomaticallyOption,

[NSNumber numberWithBool:YES],

NSInferMappingModelAutomaticallyOption,

nil];

NSError *error = nil;

if (![psc

Return Main Page Previous Page Next Page

®Online Book Reader