How to swap out a store file in Core Data

You can switch out the NSPersistentStore file in your running Core Data app by first adding your new store file, then removing the previous one. Once done you must execute your fetch request again so that the new data is available.

Hot-swapping stores assumes both NSPersistentStore files are based on the same model. It’s like replacing a USB stick.

First let’s pass a reference of the Persistent Store Coordinator into the class you’d like to make the switch in. Based on the Xcode Utility Project, that’s MainViewController. The Core Data stack is already setup in the App Delegate, so we’ll pass a reference here:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    MainViewController *controller = (MainViewController *)self.window.rootViewController;
    
    // pass on managed object context
    controller.managedObjectContext = self.managedObjectContext;
    
    // and the coordinator
    controller.persistentStoreCoordinator = self.persistentStoreCoordinator;
    return YES;
}

Now that our MainViewController can use the coordinator, here’s how we can switch to a new file. I’m calling the current one store1 and the new one store2:

- (void)swapStores {
    
    // switch out store1 and replace it with store 2
    
    AppDelegate *myAppDelegate = [[AppDelegate alloc]init];
    NSURL *store1 = [myAppDelegate.applicationDocumentsDirectory URLByAppendingPathComponent:@"Store1.sqlite"];
    NSURL *store2 = [myAppDelegate.applicationDocumentsDirectory URLByAppendingPathComponent:@"Store2.sqlite"];
    
    NSError *error = nil;
    if (![self.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:store2 options:@{NSSQLitePragmasOption: @{@"journal_mode": @"delete"}} error:&error]) {
        NSLog(@"Couldn't add the second persistent store. Error was: %@", error);
    }
    
    error = nil;
    NSPersistentStore *firstStore = [self.persistentStoreCoordinator persistentStoreForURL:store1];
    if (![self.persistentStoreCoordinator removePersistentStore:firstStore error:&error]) {
        NSLog(@"Could not remove first store. Error was: %@", error);
    }
}

Test this by fetching your data before and after the swap. You don’t have to remove the second store, you can leave it in place if you’d like to fetch data from both stores. I’m not sure though what will happen if you add data – it may end up in both stores.

To check if your store file has changed, you can subscribe to this notification:

  • NSPersistentStoreCoordinatorStoresDidChangeNotification

Here’s an iOS Demo Project that I’ve put together:





Jay is the CEO and founder of WP Hosting, a boutique style managed WordPress hosting and support service. He has been working with Plesk since version 9 and is a qualified Parallels Automation Professional. In his spare time he likes to develop iOS apps and WordPress plugins, or draw on tablet devices. He blogs about his coding journey at http://wpguru.co.uk and http://pinkstone.co.uk.