How to swap out a store file in Core Data

- by

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:



If you enjoy my content, please consider supporting me on Ko-fi. In return you can browse this whole site without any pesky ads! More details here.

Leave a Comment!

This site uses Akismet to reduce spam. Learn how your comment data is processed.