0

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Persons''*

The entity is created in the data model file and I added the core data functions to the app delegate file.

I am trying to use core data in in my first view controller which is in a tab by doing this:

- (IBAction)save:(id)sender {

NSLog(@"String is %d", [choiceSeg selectedSegmentIndex]);

NSManagedObjectContext *context = self.managedObjectContext;

Persons *person = (Persons *)[NSEntityDescription insertNewObjectForEntityForName:@"Persons" inManagedObjectContext:context];

NSNumber *ageValue = [NSNumber numberWithInt:[choiceSeg selectedSegmentIndex]];

[person setAge:ageValue];  

// Save the context
if (![context save:nil]) { 
    // error checking
}

Also, I did synthesize the managedObjectContext in my view.

What did I do wrong?

Ayrad
  • 3,996
  • 8
  • 45
  • 86
  • You should not use context in a view. Also, shouldn't it be "Person" instead of "Persons"? – Eimantas Dec 18 '11 at 11:27
  • How can i insert into core data from a view if I shouldn't use a context in a view? – Ayrad Dec 18 '11 at 11:33
  • 1
    View can't know about logic (insertion). It's only purpose is to display data. Insertion should be done in model. Action of insertion should be invoked in controller. – Eimantas Dec 18 '11 at 11:37
  • Yea. The insertion is done in my FirstViewController.m sorry about the confusion – Ayrad Dec 18 '11 at 11:41
  • Die you change your model ? If so, resetting the simulator or deleting the app might help – HeikoG Dec 18 '11 at 12:14
  • didn't work. Do I have to reference the app delegate from my view controller for this to work? right now I only have a NSManagedObjectContext *managedObjectContext property in my view controller. Perhaps I'm missing something – Ayrad Dec 18 '11 at 20:02

2 Answers2

1

This error occurs when your instance of NSManagedObjectContext is nil. The recommended way of providing a context to a view controller is by passing by reference. To pass the context from your app delegate through a UITabBarController to the first view controller is fairly simple.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)options
{
    // Assuming you don't already have a property for this (i.e. setup by a storyboard)
    UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;

    if (!tabBarController.viewControllers.count)
        return;

    FirstViewController *fvc = (FirstViewController *)[tabBarController.viewControllers objectAtIndex:0];

    // Assumes that this view controller has a public writable @property for a context.
    fvc.managedObjectContext = self.managedObjectContext;

    // ... [self.window makeKeyAndVisible]; etc...
}

I realize this isn't the greatest way to do it because tab bar items can be re-arranged and we're explicitly looking for the first one. It may be prudent to check the class of the returned view controller before attempting to set the context on it.

Mark Adams
  • 30,776
  • 11
  • 77
  • 77
  • Interesting, I will try this. I just seems ackward to me that there isn't a central context we can access form everywhere in the application. Sort of like a static class. – Ayrad Dec 19 '11 at 08:50
0

OK so I imported the AppDelegate.h into my view controller and used its managedObjectContext to enter an item in core data.

 AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = [appDelegate managedObjectContext];

It works!

I would like to know however if we have to import the delegate and get a local reference to the context every time we need to use core data.

Ayrad
  • 3,996
  • 8
  • 45
  • 86
  • 1
    Apple recommends that you pass your managed object context by reference to each view controller that requires it rather than the view controller referencing the application delegate. – Mark Adams Dec 18 '11 at 21:41
  • I prefer to do it the recommended way but how would I pass the context to my firstviewController which is a view inside a tabbbar controller(my root view i think)? – Ayrad Dec 18 '11 at 22:26
  • 1
    This seems to be the part that nobody ever answers. Tabbar controllers seem to be the least convenient, because you can't really pass the managed object context to each of its children view controllers from the app delegate without needlessly / un-lazily loading each VC in turn, just to be able to pass the context to it. – Eric G Dec 25 '11 at 00:58