Skip to content

Instantly share code, notes, and snippets.

@Morse-Code
Forked from irace/gist:5216137
Last active December 15, 2015 20:28
Show Gist options
  • Save Morse-Code/5318508 to your computer and use it in GitHub Desktop.
Save Morse-Code/5318508 to your computer and use it in GitHub Desktop.
Using Core Data as a cache; handling store migrations.
/*
Core Data is great but automatic migrations can be tricky. Migrations can take a long time, which could
result in [your app being terminated](http://stackoverflow.com/questions/13333289/core-data-timeout-adding-persistent-store-on-application-launch)
if it is happening on the main thread during application launch. Performing migrations on a background
thread is also a [bad idea](http://stackoverflow.com/a/2866725/503916), meaning your application really
needs to be able to fully launch *without a Core Data stack whatsoever* in order to safely migrate.
This can be a huge change to make to an existing app.
If you're really only using Core Data as a cache, you don't actually *need* to perform a migration.
Simply check if the existing store is compatible with your managed object model and if so, delete
and recreate it. Here's my approach for doing so. Many thanks to Marcus Zarra for being *extremely*
helpful both over Twitter and on Stack Overflow.
*/
NSString *persistentStorePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,
YES) lastObject] stringByAppendingPathComponent:@"AppName.sqlite"];
// Create managed object model
NSManagedObjectModel *managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:
[[NSBundle mainBundle] URLForResource:@"AppName"
withExtension:@"momd"]];
// Create persistent store coordinator
NSPersistentStoreCoordinator *persistentStoreCoordinator =
[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel];
// Create managed object context
managedObjectContext = [[NSManagedObjectContext alloc] init];
managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
managedObjectContext.persistentStoreCoordinator = persistentStoreCoordinator;
NSURL *persistentStoreURL = [NSURL fileURLWithPath:persistentStorePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:persistentStorePath]) {
// If store already exists, see if it is compatible with managed object model
NSError *storeMetadataError = nil;
NSDictionary *storeMetadata =
[NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType
URL:persistentStoreURL
error:&storeMetadataError];
if (storeMetadataError || ![managedObjectModel isConfiguration:nil
compatibleWithStoreMetadata:storeMetadata]) {
// Store is not compatible - wipe it
NSError *removeStoreError = nil;
[[NSFileManager defaultManager] removeItemAtPath:persistentStorePath error:&removeStoreError];
if (removeStoreError)
NSLog(@"Error removing file at path '%@': %@, %@", path, removeStoreError,
[removeStoreError userInfo]);
}
}
NSError *addStoreError = nil;
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil
URL:persistentStoreURL options:nil
error:&addStoreError])
NSLog(@"Unable to add store: %@, %@", addStoreError, [addStoreError userInfo]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment