Question

I'm getting an unrecognized selector on a newly added field to my Core Data (SQLite) db on iOS. I added a new model version as directed using Xcode's Editor menu, and then verified that new version is the current one. I made sure also that the .h and .m files for the modified table were updated, though I did this by hand (how to have these generated for you?). Nothing unusual though, just a String type field.

The problem seems to be that the lightweight migration never takes place by the time code is run that tries to reference the database object. Tring to access newFieldName gives:

-[MyEntity newFieldName]: unrecognized selector sent to instance 0x852b510
2014-03-27 13:26:21.734 ASSIST for iPad[41682:c07] *** Terminating app due to 
uncaught exception 'NSInvalidArgumentException', reason: '-[MyEntity newFieldName]:
unrecognized  selector sent to instance 0x852b510'

The line of code that generates the above error is the only line in the for loop below:

DataStoreCoreData *dStore = [[DataStoreCoreData alloc] initWithDataItemDescription:did];

for (MyEntity *myEnt in [dStore objects])
     NSString *name = [myEnt newFieldName];    

As mentioned, when I examine the SQLite db it has no new field in it, which makes sense given the error. So I also stepped through the execution of the code that is supposed to do the migration and it seems to work fine. Success. It looks like the following:

NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"ASSIST.sqlite"]];

// handle db upgrade
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                         [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                         [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];

if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error])
    NSLog(@"\r\n Fail. [error localizedDescription]: %@", [error localizedDescription]);
else
    NSLog(@"\r\n Success");

This is the 6th db version upgrade. All have been lightweight migrations with no unusual problems. Should not the above code force the SQLite db to reflect the new schema? How do I get it to do so, or is there another problem here?

Was it helpful?

Solution

I finally discovered the answer. The code I provided with the question is only part of the code required to be modified when making minimal changes to the database (lightweight migration). You also need to specify the new version when you create the object model. Notice "MyNewVersion" in the code below. You are supposed to update this parameter to reflect the new version you created and then selected as the current Model Version:

NSString *path = [[NSBundle mainBundle] pathForResource:@"MyNewVersion" ofType:@"mom" inDirectory:@"ASSIST.momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];   
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top