'+entityForName: nil is not a legal NSManagedObjectContext parameter - Core Data
Asked Answered
S

8

73

I have added all of the relevant code to the App Delegate, and I am able to add to the data model and fetch from the data model in applicationDidFinishLaunchingWithOptions.

My problem comes when I am trying to write to the data model in my View Controller. I have added this code to the header file:

NSFetchedResultsController *fetchedResultsController;
NSManagedObjectContext *managedObjectContext;

@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;

And this code to my implementation file:

NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *model = [NSEntityDescription
                          insertNewObjectForEntityForName:@"Events" 
                          inManagedObjectContext:context];
[model setValue:@"Sample Event" forKey:@"eventName"];

NSError *error;
if (![context save:&error]) {
    NSLog(@"Couldn't save: %@", [error localizedDescription]);
}

However, I get the following error:

'NSInvalidArgumentException', reason: '+entityForName: nil is not a legal NSManagedObjectContext parameter searching for entity name 'Events''

Does anyone know what's going on? Any help would be appreciated.

Subtle answered 21/7, 2012 at 22:59 Comment(2)
I think the context is nil. Make sure [self managedObjectContext] is not returning nilDrusi
Noting for posterity's sake, you can get this error if you pass the ivar for the ManagedObjectContext instead of using the getter methodSailing
D
37

If you are using segues you will get the same problems if you don't pass the context down the line. Use this code in the prepareForSegue method of class initiating the segue:

[[segue destinationViewController] setManagedObjectContext:self.managedObjectContext];

That assumes you hold your context in a property called "managedObjectContext" of course.

Decalcify answered 26/12, 2012 at 16:9 Comment(2)
I set it to _managedObjectContext and it crashes. self.mangeObjectContext solve it. Thanks!Nomism
Glad it works! I believe that, post Xcode 4.4, if you just use "@synthesize myProperty;" the compiler creates an instance variable called "myProperty" rather than "_myProperty". If you don't use "@synthesize" at all you get "_myProperty". So "_managedObjectContext" may not actually exist. I don't know because I can't see you code. "self.managedObjectContext" is safe because that calls the accessor as it always has.Decalcify
S
47

I had forgotten to pass the context to the view controller. Rookie error.

Subtle answered 21/7, 2012 at 23:26 Comment(1)
and this is the way to pass context to the view controller: AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate]; context = [appDelegate managedObjectContext];Grane
A
46

You can pass the context by including the following code before you begin to fetch the data form the database:

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
context = [appDelegate managedObjectContext];
Anabel answered 24/11, 2012 at 5:53 Comment(1)
Thanks for this nice little snippet.. I can never remember the full syntax!Snappy
D
37

If you are using segues you will get the same problems if you don't pass the context down the line. Use this code in the prepareForSegue method of class initiating the segue:

[[segue destinationViewController] setManagedObjectContext:self.managedObjectContext];

That assumes you hold your context in a property called "managedObjectContext" of course.

Decalcify answered 26/12, 2012 at 16:9 Comment(2)
I set it to _managedObjectContext and it crashes. self.mangeObjectContext solve it. Thanks!Nomism
Glad it works! I believe that, post Xcode 4.4, if you just use "@synthesize myProperty;" the compiler creates an instance variable called "myProperty" rather than "_myProperty". If you don't use "@synthesize" at all you get "_myProperty". So "_managedObjectContext" may not actually exist. I don't know because I can't see you code. "self.managedObjectContext" is safe because that calls the accessor as it always has.Decalcify
H
20

you should add this to your viewController:

 id delegate = [[UIApplication sharedApplication] delegate];
    self.managedObjectContext = [delegate managedObjectContext];
Hayman answered 20/1, 2013 at 7:53 Comment(0)
H
2

I got this problem and a colleague helped me out. If you got this error message: "entityForName: nil is not a legal NSManagedObjectContext parameter searching for entity name". And you made changes in you coredata model. I think the problem might not be the code.

The solution can be simple. Try one of those options:

  • Just delete the app from the device you are testing, it should have the old version of your model.
  • Create another database version using Xcode, >Editor>Add Model Version.

Hope it helps.

Huckaback answered 27/5, 2014 at 17:31 Comment(0)
U
2

In my case the .xcdatamodeld was mislabeled in the AppDelegate:

 let container = NSPersistentContainer(name: "name of data model")
Unwell answered 15/1, 2017 at 17:6 Comment(0)
A
0

If the destination view controller is embedded in a NavigationController, the context needs to be set appropriately as follows-

  self.mydetailViewController = [[[segue destinationViewController] viewControllers] objectAtIndex:0];
 [self.mydetailViewController setManagedObjectContext:self.managedObjectContext];
Astir answered 14/3, 2014 at 17:8 Comment(0)
B
0

I'm a fan of lazy initialization. This way if you need to inject a new context for testing you can, or it'll get it's context from the app delegate if you set up your MOC there.

class.h
@property (strong, nonatomic,getter=getManagedObjectContext) NSManagedObjectContext *managedObjectContext;

class.m
    -(NSManagedObjectContext *)getManagedObjectContext {
        if (_managedObjectContext) {
            return _managedObjectContext;
        }
        _managedObjectContext = [[(AppDelegate *)[[UIApplication sharedApplication]delegate]sharedDataModel]managedObjectContext];
        return _managedObjectContext;
    }
Backer answered 20/1, 2017 at 15:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.