I basically have the core data and the app working correctly except for the code in the AppDelegate. The code I’m having problems with is the following:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
RootViewController *tableController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain];
tableController.managedObjectContext = [self managedObjectContext];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:tableController];
[tableController release];
[window addSubview: [self.navigationController view]];
[window makeKeyAndVisible];
}
I don’t want to make the managedObjectContext the root view controller upon launch. I’m wanting to make it another view controller. However, if I change the classes to the view controller that I’m needing it for, it loads that view controller upon launch of the app, which is not what I want to do. I still want to launch the root view but I want to be able to load the core data context for my other view controller. I’m really confused on how to fix this issue. I’ve spent 2 days so far trying to find a way to fix this but no luck yet. Any help would be appreciated.
Also, if I leave out the following in the appdelegate didfinishlaunching:
RootViewController *tableController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain];
tableController.managedObjectContext = [self managedObjectContext];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:tableController];
[tableController release];
I get this error:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Hello'
EDIT:
Here is the entity code:
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Lap Times";
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addTime:)];
self.navigationItem.rightBarButtonItem = addButton;
[addButton release];
[self fetchRecords];
}
- (void)addTime:(id)sender {
addTimeEvent *event = (addTimeEvent *)[NSEntityDescription insertNewObjectForEntityForName:@"addTime" inManagedObjectContext:self.managedObjectContext];
[event setTimeStamp: [NSDate date]];
NSError *error;
if (![managedObjectContext save:&error]) {
// This is a serious error saying the record could not be saved.
// Advise the user to restart the application
}
[eventArray insertObject:event atIndex:0];
[self.tableView reloadData];
}
- (void)fetchRecords {
// Define our table/entity to use
NSEntityDescription *entity = [NSEntityDescription entityForName:@"addTime" inManagedObjectContext:self.managedObjectContext];
// Setup the fetch request
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
// Define how we will sort the records
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
[request setSortDescriptors:sortDescriptors];
[sortDescriptor release];
// Fetch the records and handle an error
NSError *error;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (!mutableFetchResults) {
// Handle the error.
// This is a serious error and should advise the user to restart the application
}
// Save our fetched data to an array
[self setEventArray: mutableFetchResults];
[mutableFetchResults release];
[request release];
}
Also if I use my own appdelegate called MyAppDelegate
MyAppDelegate *tableController = [[MyAppDelegate alloc] initWithStyle:UITableViewStylePlain];
tableController.managedObjectContext = [self managedObjectContext];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:tableController];
I get the following error:
Object cannot be set- either readonly property or no setter found
I can’t see the problem with the original approach you are taking? You are basically creating the
managedObjectContextin your App delegate and passing it on to thetableControllervia assignment.The alternative way to go about it is to get your viewController to “ask” for the managedObjectContext from the App delegate. So you’d still have your CoreData methods placed in your AppDelegate and use the following where you want to get a reference to the context. Because the managedObjectContext is lazily loaded on request, it will only get instantiated the first time you access the
managedObjectContextmethod in your app delegate.PS1: obviously you need to replace AppDelegate with the correct name for your App.
PS2: the reason you’re getting the error when you make the changes is that there is no context available for CoreData to work with.