Dave Feldman
Dave Feldman

Reputation: 194

Core Data creating extra, empty store when updating app

I'm working on an update to an app that's a few years old and uses Core Data. The previous version stores its data in Documents/app-name.sqlite. I haven't changed any of the data-related code in the update, but when I first launch the new version, it creates a new, empty data store at Library/Application Support/app-name.sqlite. I have no idea how to fix this.

The initial Core Data setup looks like this:

    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:SKCoreDataModelName withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];


    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:[SKCoreDataModelName stringByAppendingString:@".sqlite"]];
    NSError *error = nil;
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    NSDictionary *opts = [NSDictionary dictionaryWithObjectsAndKeys:
                          [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                          [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
                          nil];
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:opts error:&error]) {
        SKLogError(@"Unresolved error when creating persistent store coordinator %@, %@", error, [error userInfo]);
    }

That seems to work properly in the new version: no errors triggered, no new databases created. The problem arises when I instantiate the persistent container:

        _persistentContainer = [[NSPersistentContainer alloc] initWithName:SKCoreDataModelName];
        [_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) { ... }];

Stepping through this, I can see that when I initialize the NSPersistentContainer, the Library/Application Support folder appears in the simulator data; and when I call loadPersistentStoresWithCompletionHandler, the new sqlite file shows up.

What's going on here and, more importantly, how do I fix it? Thanks.

Upvotes: 0

Views: 195

Answers (1)

Chris Allwein
Chris Allwein

Reputation: 2578

The new NSPersistentContainer class has some conventions on where/how it creates things. By default, when you pass in {name} it will look for a model file called "{name}.momd" and will create a sqlite file in "Application Support" named "{name}.sqlite". These defaults can be overridden.

After creating your container, but before calling load, you should do this:

Swift:

let description = NSPersistentStoreDescription(url: storeURL );
_persistentContainer.persistentStoreDescriptions = [description];

Obj-C:

NSPersistentStoreDescription *_description = [NSPersistentStoreDescription persistentStoreDescriptionWithURL:storeUrl: storeUrl];
 _persistentContainer.persistentStoreDescriptions = @[description]; 

This will reset the default url to use for the store.

Upvotes: 1

Related Questions