angelokh
angelokh

Reputation: 9428

Core Data Model path vs Store path

Previously, I have an app that uses core data. I use same store url to init NSManagedObjectModel and create NSPersistentStoreCoordinator. However, in the new app, I tried to use the same way, the model can not be created. So I have to use a model url (I found it in this forum) to be able to create NSManagedObjectModel. What is the issue?

Here is from OLD app:

- (NSString *)storeName
{
    return @"ABC.storedata";
}

- (NSURL *)storeUrl
{
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:self.storeName];
    return storeURL;
}

- (NSManagedObjectModel *)managedObjectModel {
    if (_managedObjectModel == nil) {
        _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:[self storeUrl]];
    }
    return _managedObjectModel;
}


- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }    
    NSError *error = nil;
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self storeUrl] options:nil error:&error]) {

       abort();
    }    

    return _persistentStoreCoordinator;
}

Here is from NEW app:

- (NSString *)storeName
{
    return @"DEF.sqlite";
}

- (NSURL *)storeUrl
{
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:self.storeName];
    return storeURL;
}

- (NSURL *)modelUrl
{
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"DEF" withExtension:@"momd"];
    return modelURL;
}

- (NSManagedObjectModel *)managedObjectModel {
    if (_managedObjectModel == nil) {
        _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:[self modelUrl]];
    }
    return _managedObjectModel;
}


- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }    
    NSError *error = nil;
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self storeUrl] options:nil error:&error]) {

       abort();
    }    

    return _persistentStoreCoordinator;
}

Upvotes: 0

Views: 827

Answers (1)

svena
svena

Reputation: 2779

You can never use the same URL for both model and persistent store because they are two very different things.

Model URL must point to the actual model resource included in your Xcode project which is a .momd file package. Persistent store is in your case a database, a .sqlite file in documents directory.

I cannot imagine how it could have worked in the past. One possibility is that since your ABC.storedata did not have a trailing .sqlite, Core Data must have added a .sqlite to it behind the scenes and DEF.storedata could have matched your model name somehow?

This is the proper way to initialize a model where you replace "Model" with the name you have in the Xcode project for model resource:

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

As for persistent store, there are no restrictions. In most cases it should be in application documents directory though.

Upvotes: 1

Related Questions