Error when automatically migrating in core data - iphone

I am trying to migrate in core data using the automatic migration. The difference between the two versions is I added an additional attribute a model. When I attempt to add the PersistentStore to the coordinator I get the following exception
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Unrecognized column in entity'
If I remove the attribute the application loads fine (keeping the xcdatamodeld file set to the newer version or setting it to the earlier one.)
Any ideas on what could be causing this? Google turned up nothing.

What are your store options like? Mine are:
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
Also, make sure you are creating a new model version and adding your new attribute to that, and ensure that your previous model matches the current store. Are the only data models you have inside the xcdatamodeld file? And there are no others in your bundle?

Related

Error due to change in relationship

I am getting the following error message when I changed the relationship from one-to-one to one-to-many for following relationships
eventSch?.setValue(eventDesc, forKey: "eventDec")
eventDesc.setValue(eventSch, forKey: "eventSchedule")
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for
to-many relationship: property = "eventDec"; desired type = NSSet;
given type = EventDec; value = (entity:
EventDec; id: 0x60800022bcc0
;
data: {
eventSchedule = nil;
eventStatus = 0; }).'
How do I get rid of this error?
This: eventSch?.setValue(eventDesc, forKey: "eventDec") is causing errors, because you are supplying an entity; instead you should be supplying an NSSet.
I don't know Objective-C well; however, your code should look something similar to this:
NSMutableSet* eventDescSet = [NSMutableSet set];
[eventDescSet addObject: eventDesc]; // you have your set with one item
eventSch?.setValue(eventDescSet, forKey: "eventDec")
Also, I would use more descriptive names for clarity.
There is an SQL file on your device that is based on the old version, so when the app tries to load it based on the new model it can't figure out how to read it.
[Hard solution] If you have you app already published on the appstore then you should rollback your model to what it was at the time that you published, and then make a new model with your changes.
[Easy solution] If you are the only person with the app, and you are still in development there is no reason to make a model version. Just delete form your phone (and/or the simulator) and reinstall. The SQL file based on the old version will be gone.

Preparation for app release with coredata

i am coming to an end with creating version 1.0 of my new project. for the first time i am using coredata.
the application only uses 1 model, all data will be supplied by the user (so i do not load any data with the application).
of course i already working on updates for the application on different branches and see some changes in the datamodel in the future. the changes on the model will only consist of:
addition of entities
addition of attributes to existing entities
the entities do not have any relation with each other.
i have read through: iPhone app with CoreData
from there i went on to: Lightweight Migration, where i read about coredatas ability to update its model automatically if changes are minor (if i read correctly my changes are included there).
in the apple migration doc i found the code for automatic migration:
NSError *error = nil;
NSURL *storeURL = <#The URL of a persistent store#>;
NSPersistentStoreCoordinator *psc = <#The coordinator#>;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
BOOL success = [psc addPersistentStoreWithType:<#Store type#>
configuration:<#Configuration or nil#> URL:storeURL
options:options error:&error];
if (!success) {
// Handle the error.
}
my questions are the following:
where would i put this code? i found now additional information on it
do i assume that this code will only be necessary in the updated version of the app?
do i need any other preparations on my version 1.0 app to allow later motifications & updates to coredata, or do i not have to think about this in the first release?
I have this code in the method
-(NSPersistentStoreCoordinator *)persistentStoreCoordinator
There should already be code like
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
if you have let Xcode create the core data methods.
This code is only necessary in the update which introduces a new model.
As far as I know, no. This is all.

CoreData lightweight migration failing on iOS

I'm trying to migrate my core data data to a new version. The only change I've done is adding one field (NSString *sessionId)
So what I've done:
1. Create version 2 of my core data file
2. Add sessionId in this file.
3. set version 2 as default.
4. add sessionId in Offer.m and .h
5. When initializing the persistentStoreCoordinator adding the options:
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
When Im starting my application when i thought it would get the updated model i get:
Unresolved error Error
Domain=NSCocoaErrorDomain Code=134130
"The operation couldn’t be completed.
(Cocoa error 134130.)"
UserInfo=0x7643200
{URL=/Users/ei/Library/Application
Support/iPhone
Simulator/4.0.2/Applications/81B816AE-5CA0-46DB-83E7-6A765EBF9D05/Documents/Offers.sqlite, metadata={type = immutable dict,
count = 7,
Followed by
reason=Can't find model for source store
I get the same error if I don't set the options when loading the persistentStoreCoordinator
What is it I am missing?
Apparently, if you merge two models and then try to automatically migrate from one model to another doesnt work. We ended up separating them.
The error message means exactly what it says: it's missing the .xcdatamodel (or strictly .mom) that the database was saved with. I'd try grabbing the .xcdatamodel from an old revision and seeing if there have been accidental changes.
Another problem is that Xcode isn't good at deleting files which are no longer being built, both when building and when installing (Xcode is allowed to do "incremental installs" to make development quicker, and at least in previous versions, never deleted files). Instead of building MyApp.app/MyModel.mom, it's now building MyApp.app/MyModel.momd/MyModel.mom, but the old MyModel.mom might stick around and confuse whatever you're using to load the model (usually it complains about being unable to merge models, though...). The fix is to nuke the build directory and install the app using OTA/iPhone Configuration Utility/iTunes (in order of user-friendliness), and is incidentally why I tell Xcode 4 to stick build products in the project dir (the reason why they changed it is presumably because people aren't smart enough to not commit it...).

Core Data lightweight migration: Can't find or automatically infer mapping model for migration

So I created a new version of my data model, and made a previously optional field non-optional (giving it a default value). According to the documentation, this should mean my migration is eligible for lightweight, automatic migration.
I also added options that allow this when I open the store, also per the documentation:
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
When my app is starting, however, I get the following error:
"Can't find or automatically infer mapping model for migration".
Does anyone know what the problem here could be? Any help is appreciated... thanks!
You've probably looked at this, but if not ... Detecting a Lightweight Core Data Migration
In terms of other debugging code, I found this helpful:
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: #"MyDataStore.sqlite"]];
NSError *error = nil;
NSDictionary *sourceMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:storeUrl error:&error];
if (!sourceMetadata)
{
DLog(#"sourceMetadata is nil");
}
else
{
DLog(#"sourceMetadata is %#", sourceMetadata);
}
And finally, this is kind of a pain but in the Finder you can "Show Package Contents" for your app and then find a folder called .momd and within that is a file called 'VersionInfo.plist'. This has been helpful in identifying what you have and where you're trying to go.
And finally, you could try to create a mapping model and see if that works. I've wrestled with migration issues for weeks, hence the long list of desperate debugging attempts.

NSEntityMigrationPolicy subclass methods not being called

I am trying to migrate from one .xcdatamodel file to another. I have a NSEntityMigrationPolicy subclass, the name of which I have entered in xcode-> .xcmappingmodel file -> entity -> "custom Policy" field.
I run my app which successfully opens and runs the previous version of my data so I can only assume basic migration has worked. HOWEVER my NSEntityMigrationPolicy subclass methods are not being called so that I can run further migration code.
#implementation TestMigrationPolicy
- (BOOL)beginEntityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError * *)error
{
NSLog(#"this log is never shown!!!!");
return YES;
}
Does anyone have any ideas why my it might not be getting called? I am new to core data migration and I'm currently at a loss as to why this is not behaving as I feel it should.
If it helps, I am creating the persistent store like this..
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES],
NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES],
NSInferMappingModelAutomaticallyOption,
nil];
NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSLog(#"storeUrl %#", storeUrl);
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
I know this question is old but this may help others!
It's because you have the option NSInferMappingModelAutomaticallyOption set - which means lightweight migration is being run, rather than using your mapping model. Remove this option, leaving * NSMigratePersistentStoresAutomaticallyOption* in place and all should work.
I've faced the same issue. In my case this happens because Core Data is not able to found my compiled data mapping file (a file with 'cdm' extension) in the resulting application bundle. When I manually moved that file from nested bundle to the root of application bundle (MyApp.app\NestedBundle.bundle\MyMapping.cdm -> MyApp.app\MyMapping.cdm) everything worked fine. But such file layout violates current logic of application bundle structure, so I will try to make Core Data to see my cdm file in nested bundle as well.
UPD: It seems that the best solution is to use custom initialization for migration process. Very nice example can found here - http://media.pragprog.com/titles/mzcd/code/ProgressiveMigration/AppDelegate.m. I've adopted that code for searching in all bundles and it works fine.