Reputation: 721
I am creating an OSX application and I am trying to load my entities from my CoreData Entity called Service. I am using the default Xcode template and it saves my entities fine. Retrieving them however is throwing this error.
+entityForName: nil is not a legal NSManagedObjectContext parameter searching for entity name 'Service'
Here is the code throwing the error, this function is called in awakeFromNib
-( NSMutableArray * )getServices {
//NSManagedObjectContext *context = [(SAAppDelegate *)[[NSApplication sharedApplication] delegate] managedObjectContext];
SAAppDelegate *delegate = (SAAppDelegate*)[[NSApplication sharedApplication] delegate];
NSManagedObjectContext *context = [delegate managedObjectContext];
NSLog(@"After managedObjectContext: %@", context);
NSEntityDescription *entity = [ NSEntityDescription entityForName:@"Service" inManagedObjectContext: context ];
NSSortDescriptor *sortDescriptor = [ [ NSSortDescriptor alloc] initWithKey: @"service_name" ascending: YES ];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
[request setSortDescriptors:[ NSArray arrayWithObject: sortDescriptor]];
[context processPendingChanges];
NSError *error;
return [ NSMutableArray arrayWithArray: [ context executeFetchRequest:request error:&error ] ];
}
For reference here is the managedObjectContext out of the AppDelegate.m file.
//
// SAAppDelegate.m
// ServerAngel
//
// Created by Adam Bulmer on 29/10/2013.
// Copyright (c) 2013 Adam Bulmer. All rights reserved.
//
#import "SAAppDelegate.h"
@implementation SAAppDelegate
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize managedObjectContext = _managedObjectContext;
@class SAServerListWindowController;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
}
// Returns the directory the application uses to store the Core Data store file. This code uses a directory named "com.adambulmer.ServerAngel" in the user's Application Support directory.
- (NSURL *)applicationFilesDirectory
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *appSupportURL = [[fileManager URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask] lastObject];
return [appSupportURL URLByAppendingPathComponent:@"com.adambulmer.ServerAngel"];
}
// Creates if necessary and returns the managed object model for the application.
- (NSManagedObjectModel *)managedObjectModel
{
if ( _managedObjectModel == nil ) {
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"ServerAngel" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
}
return _managedObjectModel;
}
// Returns the persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. (The directory for the store is created, if necessary.)
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if ( _persistentStoreCoordinator == nil ) {
NSManagedObjectModel *mom = [ self managedObjectModel ];
NSFileManager *fileManager = [ NSFileManager defaultManager ];
NSURL *applicationFilesDirectory = [ self applicationFilesDirectory ];
NSError *error = nil;
NSDictionary *properties = [ applicationFilesDirectory resourceValuesForKeys:@[ NSURLIsDirectoryKey ] error:&error ];
if ( ! properties ) {
BOOL ok = NO;
if ( [ error code ] == NSFileReadNoSuchFileError ) {
ok = [ fileManager createDirectoryAtPath:[ applicationFilesDirectory path ] withIntermediateDirectories:YES attributes:nil error:&error ];
}
if ( ! ok ) {
[ [ NSApplication sharedApplication ] presentError:error ];
NSLog( @"1 - test" );
return nil;
}
} else {
if ( ! [ properties[ NSURLIsDirectoryKey ] boolValue ] ) {
// Customize and localize this error.
NSString *failureDescription = [NSString stringWithFormat:@"Expected a folder to store application data, found a file (%@).", [applicationFilesDirectory path]];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setValue:failureDescription forKey:NSLocalizedDescriptionKey];
error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:101 userInfo:dict];
[ [ NSApplication sharedApplication ] presentError:error ];
NSLog( @"2 - test" );
return nil;
}
}
NSURL *url = [applicationFilesDirectory URLByAppendingPathComponent:@"ServerAngel.storedata"];
NSPersistentStoreCoordinator *coordinator = [ [ NSPersistentStoreCoordinator alloc ] initWithManagedObjectModel:mom ];
if ( ! [ coordinator addPersistentStoreWithType:NSXMLStoreType configuration:nil URL:url options:nil error:&error ] ) {
[ [ NSApplication sharedApplication] presentError:error ];
return nil;
}
NSLog(@"AppDelegate coordinator: %@", coordinator);
_persistentStoreCoordinator = coordinator;
}
return _persistentStoreCoordinator;
}
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
- (NSManagedObjectContext *)managedObjectContext
{
if ( _managedObjectContext == nil ) {
_managedObjectContext = [ [ NSManagedObjectContext alloc ] init ];
NSPersistentStoreCoordinator *coordinator = [ self persistentStoreCoordinator ];
if ( coordinator != nil ) {
[ _managedObjectContext setPersistentStoreCoordinator: coordinator ];
}
NSLog(@"AppDelegate coordinator: %@", coordinator);
}
NSLog(@"AppDelegate managedObjectContext: %@", _managedObjectContext);
return _managedObjectContext;
}
// Returns the NSUndoManager for the application. In this case, the manager returned is that of the managed object context for the application.
- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window
{
return [[self managedObjectContext] undoManager];
}
// Performs the save action for the application, which is to send the save: message to the application's managed object context. Any encountered errors are presented to the user.
- (IBAction)saveAction:(id)sender
{
NSError *error = nil;
if (![[self managedObjectContext] commitEditing]) {
NSLog(@"%@:%@ unable to commit editing before saving", [self class], NSStringFromSelector(_cmd));
}
if (![[self managedObjectContext] save:&error]) {
[[NSApplication sharedApplication] presentError:error];
}
}
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
// Save changes in the application's managed object context before the application terminates.
if (!_managedObjectContext) {
return NSTerminateNow;
}
if (![[self managedObjectContext] commitEditing]) {
NSLog(@"%@:%@ unable to commit editing to terminate", [self class], NSStringFromSelector(_cmd));
return NSTerminateCancel;
}
if (![[self managedObjectContext] hasChanges]) {
return NSTerminateNow;
}
NSError *error = nil;
if (![[self managedObjectContext] save:&error]) {
// Customize this code block to include application-specific recovery steps.
BOOL result = [sender presentError:error];
if (result) {
return NSTerminateCancel;
}
NSString *question = NSLocalizedString(@"Could not save changes while quitting. Quit anyway?", @"Quit without saves error question message");
NSString *info = NSLocalizedString(@"Quitting now will lose any changes you have made since the last successful save", @"Quit without saves error question info");
NSString *quitButton = NSLocalizedString(@"Quit anyway", @"Quit anyway button title");
NSString *cancelButton = NSLocalizedString(@"Cancel", @"Cancel button title");
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:question];
[alert setInformativeText:info];
[alert addButtonWithTitle:quitButton];
[alert addButtonWithTitle:cancelButton];
NSInteger answer = [alert runModal];
if (answer == NSAlertAlternateReturn) {
return NSTerminateCancel;
}
}
return NSTerminateNow;
}
@end
Error logs
2013-11-14 22:01:38.267 ServerAngel[1012:303] Network check
2013-11-14 22:01:48.161 ServerAngel[1012:303] network avi
2013-11-14 22:01:48.162 ServerAngel[1012:303] After managedObjectContext: (null)
2013-11-14 22:01:48.162 ServerAngel[1012:303] +entityForName: nil is not a legal NSManagedObjectContext parameter searching for entity name 'Service'
2013-11-14 22:01:48.163 ServerAngel[1012:303] (
0 CoreFoundation 0x00007fff877c941c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff85c31e75 objc_exception_throw + 43
2 CoreData 0x00007fff8d202729 +[NSEntityDescription entityForName:inManagedObjectContext:] + 217
3 ServerAngel 0x0000000100002d9d -[SAServerListWindowController getServices] + 205
4 ServerAngel 0x0000000100003294 -[SAServerListWindowController checkServices] + 148
5 Foundation 0x00007fff894d1094 __NSFireTimer + 96
6 CoreFoundation 0x00007fff87730724 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
7 CoreFoundation 0x00007fff8773025f __CFRunLoopDoTimer + 1151
8 CoreFoundation 0x00007fff877a176a __CFRunLoopDoTimers + 298
9 CoreFoundation 0x00007fff876ebaa5 __CFRunLoopRun + 1525
10 CoreFoundation 0x00007fff876eb275 CFRunLoopRunSpecific + 309
11 HIToolbox 0x00007fff8e4b3f0d RunCurrentEventLoopInMode + 226
12 HIToolbox 0x00007fff8e4b3cb7 ReceiveNextEventCommon + 479
13 HIToolbox 0x00007fff8e4b3abc _BlockUntilNextEventMatchingListInModeWithFilter + 65
14 AppKit 0x00007fff8ef1828e _DPSNextEvent + 1434
15 AppKit 0x00007fff8ef178db -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
16 AppKit 0x00007fff8ef0b9cc -[NSApplication run] + 553
17 AppKit 0x00007fff8eef6803 NSApplicationMain + 940
18 ServerAngel 0x00000001000049a2 main + 34
19 libdyld.dylib 0x00007fff88cbf5fd start + 1
)
2013-11-14 22:01:48.255 ServerAngel[1012:303] Network check
Upvotes: 2
Views: 3164
Reputation: 119242
Your accessor method for the managed object context is not being called - you're not even seeing the logs from the lazy loading method.
My guess is that the application delegate is not connected correctly. If you use the debugger you will probably see that this line:
SAAppDelegate *delegate = (SAAppDelegate*)[[NSApplication sharedApplication] delegate];
Is returning nil
.
OS X applications do not have a delegate by default, you have to set them up specifically, usually by adding an object to the main xib file, identifying it as your delegate class and connecting it to the delegate outlet of the application object.
If that is connected (and since you're saying that you've used the default template, so that does come with everything out of the box) then the problem must be that you're calling this from the wrong awakeFromNib
method or you've added some other nib file that doesn't have things set up properly.
Upvotes: 2
Reputation: 7381
Your managedObjectContext
is not being instantiated for all cases. You can simplify your accessor and ensure the MOC is never nil with this accessor.
- (NSManagedObjectContext *)managedObjectContext
{
if (_managedObjectContext == nil)
{
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:[self persistentStoreCoordinator]];
}
return _managedObjectContext;
}
You may need to alter the accessor for persistantStoreCoordinator
in a similar fashion to ensure it lazily instantiates as well.
Upvotes: 2