views:

67

answers:

1

This is a follow on from my previous problems here. Resetting the simulator solved all my troubles before, and I've gone on to complete my App.

I now have the exact same problem when installing the app onto my iPhone device. It picks up an old version of my database, which doesn't have the second entity in it, and crashes when I try to access the second entity:

2010-04-22 23:52:18.860 albumCloud[135:207] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Image''
2010-04-22 23:52:18.874 albumCloud[135:207] Stack: (
  843263261,
  825818644,
  820669213,
  20277,
  844154820, 
  16985,   
  14633,   
  844473760,   
  844851728,   
  862896011,   
  843011267,   
  843009055,   
  860901832,   
  843738160,   
  843731504,   
  11547,   
  11500   
 )

terminate called after throwing an instance of 'NSException'

I have two questions:

1) How on earth do I delete my app thoroughly enough from my phone that it removes the old data? (I've so far tried regular app deletion, deleting and then holding home and power for a reboot, cursing at and threatening the app while running it... everything)

2) How do I prevent this happening when my application is in the App store, and I for some reason decide that I want to add another entity to the store, or another attribute to the existing entities? is there an "if x doesn't exist then create it" method?

A: 

To fully delete the app, deleting it by the usual method should work, i.e. hold down until it wiggles and tap the delete button. Then connect to iTunes. It may be that iTunes is restoring the app and its backed up data each time.

To support adding new entities later on, you want to use versioning and automatic light-weight migration which is described here:

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/vmLightweight.html#//apple_ref/doc/uid/TP40008426-SW1

Basically you create a new version of your data model using the Design->Data Model menu item in Xcode, then make a few code changes. This will cause Core Data to automatically migrate an older model to the newer one. You are limited in what kinds of changes you can make. You can add new entities, and either add optional attribute to existing entities, or required attributes with default values set.

One thing that caught me out is that the way you load the core data NSManagedObjectModel changes when you want to use versioning and migration. Without migration you probably have this:

NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];

Once you start using versioning and migration this needs to change to something like this:

NSString *path = [[NSBundle bundleForClass:self.class] pathForResource:@"DataModelName"
                                                                ofType:@"momd"];
NSURL *url = [NSURL fileURLWithPath:path];
NSManagedObjectModel *model = [[[NSManagedObjectModel alloc] initWithContentsOfURL:url] autorelease];
Mike Weller
Martin KS