Home > Articles > Home & Office Computing > Mac OS X

  • Print
  • + Share This
  • 💬 Discuss
Like this article? We recommend

Like this article? We recommend

Adjusting Your Code

By default, data migration is not turned on for any application. Fortunately it is very easy to turn on automatic code migration, but the manner in which you turn it on is dependent on the type of application you are designing. When it comes to Core Data, there are two application models that differ drastically in their handling of the Core Data Stack: the document model and the non-document model.

Document Model

In a document model, each document has its own Core Data stack that is constructed when the NSPersistentDocument is initialized. In this case, to enable Core Data automatic migration you simply need to override one method call in your subclass of the NSPersistentDocument:

- (BOOL)configurePersistentStoreCoordinatorForURL:ofType:modelConfiguration:storeOptions:error:

When Core Data attempts to load a persistent store, this method is called. To turn on automatic migration, all that is needed is to add the option in the store options as follows:

- (BOOL)configurePersistentStoreCoordinatorForURL:(NSURL*)url 
                      ofType:(NSString*)fileType
                modelConfiguration:(NSString*)configuration
                   storeOptions:(NSDictionary*)storeOptions
                      error:(NSError**)error
{
  NSMutableDictionary *options = nil;
  if (storeOptions != nil) {
    options = [storeOptions mutableCopy];
  } else {
    options = [NSMutableDictionary alloc] init];
  }

  [options setObject:[NSNumber numberWithBool:YES] 
        forKey:NSMigratePersistentStoresAutomaticallyOption];

  BOOL result = [super configurePersistentStoreCoordinatorForURL:url
                              ofType:fileType
                        modelConfiguration:configuration
                           storeOptions:options
                               error:error];
  [options release], options = nil;
  return result;
}

Once you have set the NSMigratePersistentStoresAutomaticallyOption flag, Core Data will attempt to automatically migrate any persistent store that does not match the store that is flagged as current.

Non-Document Model

Things are a bit different in a non–document-based application. Generally, the loading and handling of the Core Data stack is performed in the application delegate instead of in a document object. Therefore configuring Core Data to do automatic migration is also a bit different.

Normally, a non–document-based application will have a method to load up the persistent store that looks something like the following:

- (NSPersistentStoreCoordinator *) persistentStoreCoordinator
{
  if (persistentStoreCoordinator) return persistentStoreCoordinator;

  NSFileManager *fileManager = [NSFileManager defaultManager];
  NSString *applicationSupportFolder = [AbstractManagedObject applicationSupportFolder];
  if ( ![fileManager fileExistsAtPath:applicationSupportFolder isDirectory:NULL] ) {
    [fileManager createDirectoryAtPath:applicationSupportFolder attributes:nil];
  }

  NSURL *url = [NSURL fileURLWithPath: [applicationSupportFolder stringByAppendingPathComponent: @"MyApplication.xml"]];
  persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
  NSError *error = nil;
  if (![persistentStoreCoordinator addPersistentStoreWithType:NSXMLStoreType 
                         configuration:nil 
                              URL:url 
                            options:nil 
                             error:&error]) {
    [[NSApplication sharedApplication] presentError:error];
  }

  return persistentStoreCoordinator;
}

The only change that is required to turn on automatic store migration is to add the option, similar to the document model above, to the -(id)addPersistentStoreWithType: configuration: URL: options: error: method. You can see the change in the updated method below:

- (NSPersistentStoreCoordinator *) persistentStoreCoordinator
{
  if (persistentStoreCoordinator) return persistentStoreCoordinator;

  NSFileManager *fileManager = [NSFileManager defaultManager];
  NSString *applicationSupportFolder = [AbstractManagedObject applicationSupportFolder];
  if ( ![fileManager fileExistsAtPath:applicationSupportFolder isDirectory:NULL] ) {
    [fileManager createDirectoryAtPath:applicationSupportFolder attributes:nil];
  }

  NSURL *url = [NSURL fileURLWithPath: [applicationSupportFolder stringByAppendingPathComponent: @"MyApplication.xml"]];
  persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
  NSError *error = nil;

  //Turn on automatic store migration
  NSMutableDictionary *optionsDictionary = [NSMutableDictionary dictionary];
  [optionsDictionary setObject:[NSNumber numberWithBool:YES] 
             forKey:NSMigratePersistentStoresAutomaticallyOption];

  if (![persistentStoreCoordinator addPersistentStoreWithType:NSXMLStoreType 
                         configuration:nil 
                              URL:url 
                            options:nil 
                             error:&error]) {
    [[NSApplication sharedApplication] presentError:error];
  }

  return persistentStoreCoordinator;
}

With that one change, Core Data will detect and migrate your persistent stores automatically.

  • + Share This
  • 🔖 Save To Your Account

Discussions

comments powered by Disqus