4

Hello I am testing my core data application in device, but it is crashing in iphone and working fine in simulator.Here is my code..

- (NSManagedObjectContext *)managedObjectContext {

    if (managedObjectContext != nil) {
        return managedObjectContext;

    }
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        managedObjectContext = [[NSManagedObjectContext alloc] init];
        [managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return managedObjectContext;
}



- (NSManagedObjectModel *)managedObjectModel {

    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"TouristGuide" withExtension:@"momd"];
    managedObjectModel= [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];    
    NSLog(@"%@", modelURL);
    return managedObjectModel;
}


- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {


    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }

    NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:@"TouristGuide.sqlite"];


    NSFileManager *fileManager = [NSFileManager defaultManager];
    // If the expected store doesn't exist, copy the default store.
    if (![fileManager fileExistsAtPath:storePath]) {
        NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"TouristGuide" ofType:@"sqlite"];
        if (defaultStorePath) {
            [fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
        }
    }

    NSURL *storeUrl = [NSURL fileURLWithPath:storePath];


    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];    
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];


    NSError *error;
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
        // Update to handle the error appropriately.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    }    


    return persistentStoreCoordinator;
}

device log is showing exception in line:

persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];

The exceptions are cannot create nspersistancecordinator with a nil model and second is cannot find Entity 'City'.

How can I solve this problem?

Crash log

0x352d1de0 -[NSPersistentStoreCoordinator initWithManagedObjectModel:] + 252 10  TouristGuide                   
0x0000358e -[TouristGuideAppDelegate persistentStoreCoordinator] (TouristGuideAppDelegate.m:176) 11  TouristGuide                  
0x0000310e -[TouristGuideAppDelegate managedObjectContext] (TouristGuideAppDelegate.m:124) 12  TouristGuide     
0x000041f6 -[CityViewController viewDidLoad] (CityViewController.m:43)
TechZen
  • 64,370
  • 15
  • 118
  • 145
iProgrammer
  • 3,099
  • 3
  • 33
  • 59

2 Answers2

18

Hold down the option key, go to Product menu (Xcode 4) and do "Clean Build Folder"... then let off the option key, and do "Clean"...

Now do Product menu > Analyze and make sure all is kosher.

Lastly go to the left hand panel of the project viewer, and click on the icon that represents your entire project. In the window that comes up in the main panel, under "Targets," click on your app. Now click "Build Phases" and expand "Copy Bundle Resources." Make sure that your TouristGuide.xcdatamodeld file is there. Next, expand "Link Binary with Libraries" and make sure that "CoreData.framework" is in there (if you added Core Data to an existing project that didn't start out as a Core Data project, then chances are, it's not in there). Next, expand "Compile Sources" and, of course, double-check that all your model classes are in there (y'know, the NSManagedObject custom sub-classes).

Speaking of those model classes... now click on your TouristGuide.xcdatamodeld and click on the "Default" configuration. Make sure any classes that say "NSManagedObject" in the "Class" column do NOT have custom classes, and if they do list a custom class, make sure you have the equivalently-named .h and .m files corresponding to those.

10-to-1 it's something to do with your model file itself. Onetime I changed my model file's full path (it should be /Users/You/Documents/Developer/MyApp/MyModel.xcdatamodeld/MyModel.xcdatamodel). Once I had changed it, I couldn't figure out how to change it back, because MyModel.xcdatamodeld is a "package" file, not a folder. Sure, in the finder, you can do "Show Package Contents...", but XCode's dialog box for picking the file's location refused to navigate into the package contents! SO I was unable to ever re-select the .xcdatamodel file that resides within the .xcdatamodeld file! I had to totally recreate my entire model file from scratch, it was a huge pain. Maybe there's a way to do it but I couldn't figure it out.

Also, two last tricks.

First last trick, try this on a backup of your project just in case, but it worked for me when I got stuck: change your code from this:

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"TouristGuide" withExtension:@"momd"];

to this:

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"TouristGuide" withExtension:@"mom"];

...change "momd" to "mom".

Then delete the app from device or simulator, "Clean build folder," "clean," and rebuild and re-run the project. It might give you errors, it might not. After that, then change it back to "momd" and redo all those steps. Changing this will might make XCode delete more stuff than it otherwise would when you do "Clean Build Folder" and reinstall the app. That way it's making a fresh "momd" file when you switch back.

Second last trick:

It also never hurts to #import in your headers, just for good luck. :D

Hope this helps. If someone would have told me this stuff at the beginning it would have saved me a lot of time.

TechZen
  • 64,370
  • 15
  • 118
  • 145
CommaToast
  • 11,370
  • 7
  • 54
  • 69
  • 1
    A `mom` file is an unversioned file and a `momd` is a versioned one. – TechZen Jul 15 '11 at 19:19
  • Correct; a .momd contains one or several .mom files, right? But my hope was that changing the file type to the wrong one temporarily might "confuse" Xcode into thinking it has to rebuild it, which could help matters if there was some problem in how it was built. Kind of a last-ditch type thing, if deleting off the device doesn't help, since I've heard of times where it doesn't (like if the device is jail-broken or maybe if you're not building the release). – CommaToast Jul 15 '11 at 19:50
  • I expanded "Copy Bundle Resources." and not having TouristGuide.xcdatamodeld file in it..how can I add this – iProgrammer Jul 16 '11 at 05:50
  • Absolutely beautiful answer! Wow. Suddenly this issue cropped up on me just on the release build. It turned out that my xcdatamodeld was not in the Copy Bundle Resources. However, this bug did not come up until xCode 6.3. I'm sure it must be a bug because I can't find any changes since the last successful deployment. Anyhow, I learned my lesson and will always test on a release build! Thanx for the great post. – SmileBot Apr 13 '15 at 00:54
  • You're welcome. I'm glad that this answer is still helping people 4 years later. But not so glad that Apple still hasn't made this more bulletproof by now... CBA... just like all the Yosemite kernel panics and lag... sigh... – CommaToast Apr 14 '15 at 06:52
1

The error is actually caused by the self.managedObjectModel property having a nil value. Look at the method where the managedObjectModel is loaded. That is the source of your problem.

Sometimes, Xcode does not remove previous versions of files from development builds on either the simulator or device. The solution is to manually delete the entire app of device and have Xcode rebuild it from scratch.

TechZen
  • 64,370
  • 15
  • 118
  • 145