I'm using the Utility Application Template with Core Data. In the flipside view, user can add items and these items brand and model feed a UIPickerView on the main view.
When the user adds an item, unless she or he closes the app this added item does not appear in the picker row titles.
How can I load this title without closing the app?
Thanks
Edit to add code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//retrieving data from iGear.xcdatamodeld
iGearAppDelegate *iGearDelegate = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = [iGearDelegate managedObjectContext];
NSError *error;
if (managedObjectContext !=nil) {
if ([managedObjectContext hasChanges] && [managedObjectContext save:&error]) {
//NSLog(#"Retrieving: unresolved error %#, %#",error, [error userInfo]);
abort();
}
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Cogset" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
//#pragma mark UIPickerView
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent: (NSInteger)component
{
return [fetchedObjects count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (component == 0)
{
cogset = [fetchedObjects objectAtIndex:row];
return [NSString stringWithFormat:#"%# %#",cogset.brand,cogset.model];
}
return #"";
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
cassette = [fetchedObjects objectAtIndex:[_chooseCogsetPickerView selectedRowInComponent:0]];
}
You should implement a UIPickerViewDelegate for your UIPickerView.
Then, use this delegate function to populate your picker view:
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component ]
{
return someValue;
}
I can try to help you more specifically if you post some actual code with what's currently happening.
Related
I'm currently creating an application to rank teams based on different criteria, and I would like to give users the option to sort the teams in a table view based on those different criteria. I use core data in my app to store my teams, and am using a navigation-based template that starts by showing the user a table view with the option to click on each cell to edit a team. An example of what I want to do is how the Errands app lets you sort your tasks by Due date, priority, alphabetical, and manual.
I tried creating buttons that called a method to change, the sortDescriptor key, but I have to recreated the fetchedResultsController every time for this to update (i.e. don't check if the fetchedResultsController_ ! = nil), and that seems to copy the cell that is changing positions into the new position rather than moving it there.
How should I go about coding a sort button that lets the user change the criteria by which the table is sorted and correctly update the table? I've read a lot of posts concerning the fetchResultsController and NSSortDescriptors, but the solutions seem to be a one-time deal.
I could really use some help, or reference to a tutorial that shows how to do this.
Here is my RootViewController.m:
#import "RootViewController.h"
#import "TeamViewController.h"
#interface RootViewController ()
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath;
#end
#implementation RootViewController
#synthesize fetchedResultsController=fetchedResultsController_;
#synthesize managedObjectContext=managedObjectContext_;
#synthesize sortParam;
//#synthesize sortDescriptors;
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
NSLog(#"viewDidLoad called");
sortParam = #"totalRank";
[super viewDidLoad];
self.title = #"Title";
// Set up the edit and add buttons.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(showTeamView)];
self.navigationItem.rightBarButtonItem = addButton;
[addButton release];
UIBarButtonItem* button1 = [[[UIBarButtonItem alloc] initWithTitle:#"Rank" style:UIBarButtonItemStyleBordered target:self action:#selector(reSort1:)] autorelease];
UIBarButtonItem* button2 = [[[UIBarButtonItem alloc] initWithTitle:#"Name" style:UIBarButtonItemStyleBordered target:self action:#selector(reSort2:)] autorelease];
[self setToolbarItems:[NSArray arrayWithObjects:button1, button2, nil]];
}
-(void)showTeamView {
NSLog(#"showTeamView called");
TeamViewController *teamViewController = [[TeamViewController alloc] initWithRootController:self team:nil];
[self presentModalViewController:teamViewController animated:YES];
[teamViewController release];
}
// Implement viewWillAppear: to do additional setup before the view is presented.
- (void)viewWillAppear:(BOOL)animated {
NSLog(#"viewWillAppear called");
// sortParam = #"totalRank";
[super viewWillAppear:animated];
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
NSLog(#"configureCell:atIndexPath called");
NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSString *textLabelText = [NSString stringWithFormat:#"%# - %#", [[managedObject valueForKey:#"teamName"]description], [[managedObject valueForKey:#"teamNumber"]description]];
// NSLog(textLabelText);
cell.textLabel.text = textLabelText;//[[managedObject valueForKey:#"teamName"] description];
cell.detailTextLabel.text = [[managedObject valueForKey:#"totalRank"] description];
// cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
}
- (void)reSort1:(id)sender {
NSLog(#"reSort1 called by: %#", sender);
sortParam = #"totalRank";
[self.tableView reloadData];
[self viewDidLoad];
}
- (void)reSort2:(id)sender {
NSLog(#"resort2 called by %#", sender);
sortParam = #"teamName";
[self.tableView reloadData];
[self viewDidLoad];
}
#pragma mark -
#pragma mark Add a new object
-(void)insertTeamWithName:(NSString *)teamName teamNumber:(NSString *)teamNumber noteField:(NSString *)noteField driveTrain:(NSString *)driveTrain autoRank:(NSNumber *)autoRank offenseRank:(NSNumber *)offenseRank defenseRank:(NSNumber *)defenseRank speedRank:(NSNumber *)speedRank shooterRank:(NSNumber *)shooterRank totalRank:(NSNumber *)totalRank{
// Create a new instance of the entity
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
// Configure the team
[newManagedObject setValue:teamName forKey:#"teamName"];
[newManagedObject setValue:teamNumber forKey:#"teamNumber"]; //new
[newManagedObject setValue:noteField forKey:#"noteField"];
[newManagedObject setValue:autoRank forKey:#"autoRank"];
[newManagedObject setValue:driveTrain forKey:#"driveTrain"];
[newManagedObject setValue:offenseRank forKey:#"offenseRank"];
[newManagedObject setValue:defenseRank forKey:#"defenseRank"];
[newManagedObject setValue:speedRank forKey:#"speedRank"];
[newManagedObject setValue:shooterRank forKey:#"shooterRank"];
/* [newManagedObject setValue:armRank forKey:#"armRank"];
[newManagedObject setValue:speedRank forKey:#"speedRank"]; */
[newManagedObject setValue:totalRank forKey:#"totalRank"];
[self saveContext];
NSLog(#"insertTeamWithNameCalled");
}
- (void)saveContext {
// Create a new instance of the entity managed by the fetched results controller.
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
// Save the context.
NSError *error = nil;
if (![context save:&error]) {
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
*/
NSLog(#"Unresolved error in saveContext %#, %#", error, [error userInfo]);
// abort();
}
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
// Prevent new objects being added when in editing mode.
[super setEditing:(BOOL)editing animated:(BOOL)animated];
self.navigationItem.rightBarButtonItem.enabled = !editing;
}
#pragma mark -
#pragma mark Table view data source
/*
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
}
*/
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [[self.fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"tableView:cellForRowAtIndexPath called");
static NSString *CellIdentifier = #"TableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the managed object for the given index path
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
[context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];
// Save the context.
[self saveContext];
}
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// The table view should not be re-orderable.
return NO;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSManagedObject *team = [[self fetchedResultsController] objectAtIndexPath:indexPath];
TeamViewController *teamViewController = [[TeamViewController alloc] initWithRootController:self team:team];
[self presentModalViewController:teamViewController animated:YES];
[teamViewController release];
}
#pragma mark -
#pragma mark Fetched results controller
- (NSFetchedResultsController *)fetchedResultsController {
NSLog(#"fetchResultsController called");
/*
if (fetchedResultsController_ != nil) {
return fetchedResultsController_;
}
*/
/*
Set up the fetched results controller.
*/
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Team" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortParam ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSLog(#"sortParam == %#", sortParam);
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:#"Root"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
NSError *error = nil;
if (![fetchedResultsController_ performFetch:&error]) {
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
*/
NSLog(#"Unresolved error in fetchedResultsController %#, %#", error, [error userInfo]);
// abort();
}
return fetchedResultsController_;
}
#pragma mark -
#pragma mark Fetched results controller delegate
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
NSLog(#"controllerWillChangeContent called");
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
NSLog(#"controller:didChangeObject called");
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
NSLog(#"controllerDidChangeContent called");
[self.tableView endUpdates];
}
/*
// Implementing the above methods to update the table view in response to individual changes may have performance implications if a large number of changes are made simultaneously. If this proves to be an issue, you can instead just implement controllerDidChangeContent: which notifies the delegate that all section and object changes have been processed.
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// In the simplest, most efficient, case, reload the table view.
[self.tableView reloadData];
}
*/
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
}
- (void)dealloc {
[fetchedResultsController_ release];
[managedObjectContext_ release];
// [sortParam release];
[super dealloc];
}
#end
My data for for an entity's attribute is not being fetched upon restart or not being saved before quitting (could be either case). The bottom line is, the data is not showing up in the table upon restart. I think I may need to consolidate my core data methods or move them to the app delegate file instead.
I think my core data code is all messed up, can anyone help fix it?
Let me know if you need any additional code to look at from the appdelegate.m etc.
Here is the code for my View Controller:
#import "RoutineTableViewController.h"
#import "AlertPrompt.h"
#import "Routine.h"
#import "CurlAppDelegate.h"
#implementation RoutineTableViewController
#synthesize tableView;
#synthesize eventsArray;
#synthesize managedObjectContext;
- (void)dealloc
{
[managedObjectContext release];
[eventsArray release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (NSManagedObjectContext *) managedObjectContext {
if (managedObjectContext != nil) {
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator: coordinator];
}
return managedObjectContext;
}
-(void)addEvent
{
Routine *routine = (Routine *)[NSEntityDescription insertNewObjectForEntityForName:#"Routine" inManagedObjectContext:managedObjectContext];
CurlAppDelegate *curlAppDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [curlAppDelegate managedObjectContext];
NSManagedObject *newRoutineEntry;
newRoutineEntry = [NSEntityDescription insertNewObjectForEntityForName:#"Routine" inManagedObjectContext:context];
NSError *error = nil;
if (![managedObjectContext save:&error]) {
// Handle the error.
}
[eventsArray insertObject:routine atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
CurlAppDelegate *curlAppDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [curlAppDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Routine" inManagedObjectContext:context];
[request setEntity:entity];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[context executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
// Handle the error.
}
[self setEventsArray:mutableFetchResults];
[mutableFetchResults release];
[request release];
UIBarButtonItem * addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(showPrompt)];
[self.navigationItem setLeftBarButtonItem:addButton];
[addButton release];
UIBarButtonItem *editButton = [[UIBarButtonItem alloc]initWithTitle:#"Edit" style:UIBarButtonItemStyleBordered target:self action:#selector(toggleEdit)];
self.navigationItem.rightBarButtonItem = editButton;
[editButton release];
[super viewDidLoad];
}
-(void)toggleEdit
{
[self.tableView setEditing: !self.tableView.editing animated:YES];
if (self.tableView.editing)
[self.navigationItem.rightBarButtonItem setTitle:#"Done"];
else
[self.navigationItem.rightBarButtonItem setTitle:#"Edit"];
}
-(void)showPrompt
{
AlertPrompt *prompt = [AlertPrompt alloc];
prompt = [prompt initWithTitle:#"Add Workout Day" message:#"\n \n Please enter title for workout day" delegate:self cancelButtonTitle:#"Cancel" okButtonTitle:#"Add"];
[prompt show];
[prompt release];
}
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex])
{
NSString *entered = [(AlertPrompt *)alertView enteredText];
if(eventsArray && entered)
{
[eventsArray addObject:entered];
[tableView reloadData];
}
}
}
- (void)viewDidUnload
{
self.eventsArray = nil;
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [eventsArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellEditingStyleDelete reuseIdentifier:CellIdentifier] autorelease];
cell.textLabel.text = [self.eventsArray objectAtIndex:indexPath.row];
return cell;
}
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the managed object at the given index path.
NSManagedObject *eventToDelete = [eventsArray objectAtIndex:indexPath.row];
[managedObjectContext deleteObject:eventToDelete];
// Update the array and table view.
[eventsArray removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
// Commit the change.
NSError *error = nil;
if (![managedObjectContext save:&error]) {
// Handle the error.
}
}
}
#end
And here is the data model:
Edit:
Added PersisentStoreCoordinater Method (From App Delegate):
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (__persistentStoreCoordinator != nil)
{
return __persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"Curl.sqlite"];
NSError *error = nil;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
{
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
Typical reasons for an error here include:
* The persistent store is not accessible;
* The schema for the persistent store is incompatible with current managed object model.
Check the error message to determine what the actual problem was.
If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.
If you encounter schema incompatibility errors during development, you can reduce their frequency by:
* Simply deleting the existing store:
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]
* Performing automatic lightweight migration by passing the following dictionary as the options parameter:
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.
*/
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return __persistentStoreCoordinator;
}
Here's a couple of tips to fix this :
Remove all references to managedObjectContext, etc. in your RoutineViewController. Only reference the CoreData classes / properties from your AppDelegate.
Whenever you need a reference (say in your AddEvent method) reference the appropriate objects from your delegate (see code below)
When this gets more complex, you'll probably want a DataManager class that handles ALL your CoreData objects. Make it a Singleton, and you'll be able to reference it in any class. For fetching objects for display, you can then create the necessary methods in this class to retrieve these objects in a NSMutableArray
CurlAppDelegate *curlAppDelegate = [[UIApplication sharedApplication] delegate]; NSManagedObjectContext *context = [curlAppDelegate managedObjectContext];
Routine *routine = (Routine *)[NSEntityDescription insertNewObjectForEntityForName:#"Routine" inManagedObjectContext:context];
See how you're now using the context from your AppDelegate and not locally? This is important, because your app will link your xdatamodel from your Bundle into your AppDelegate on initialization.
If you're concerned about the data not being saved, or overwritten, check out your AppDelegate's - (NSPersistentStoreCoordinator *)persistentStoreCoordinator
That's where the setup happens to link to your stored database when you exit and enter the app. Here's your code (modified) in your AppDelegate that loads in the Curl.sqlite file :
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator{
if (__persistentStoreCoordinator != nil)
{
return __persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"Curl.sqlite"];
NSError *error = nil;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
{
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return __persistentStoreCoordinator;
}
My guess would be that your are mixing up your managed object contexts. Inserting into one and attempting to save on another. Remove your Core Data associated methods in your view controller and just try going through your app delegate methods. The data will either then be saved correctly, or an error will be tossed by Core Data. Make sure to inspect any setup/save errors in your Core Data code.
Have you attached your core data file in your Main Bundle? There are two types of Bundle in iPhone app. Main Bundle and Application Bundle. We had a scenario something like yours. We copied the database into our main bundle and write the location of the database into our code. then it worked fine. you can check on this issue also.
Ive made a few threads on this subject related to errors etc, but they've all done different things and I can't get the core data to work still. Ill fix one problem then theres another, etc.
What is supposed to happen:
User is in routineViewControler and clicks on + button in nav bar. UIAlert with text input comes up. User input text and it should become title for a new cell in the table and be saved using Core Data. It should be saved to "name" attribute (String) within the "Routine" entity.
Right now it is not saving or it is not fetching.
Here is my data model:
AppDelegate:
#import "CurlAppDelegate.h"
#import "ExcerciseNavController.h"
#import "RoutineTableViewController.h"
#implementation CurlAppDelegate
#synthesize window=_window;
#synthesize rootController;
#synthesize excerciseNavController;
#synthesize managedObjectContext=__managedObjectContext;
#synthesize managedObjectModel=__managedObjectModel;
#synthesize persistentStoreCoordinator=__persistentStoreCoordinator;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[self.window addSubview:rootController.view];
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
/*
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
*/
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
/*
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
*/
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
/*
Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
*/
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
/*
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
*/
}
- (void)applicationWillTerminate:(UIApplication *)application
{
/*
Called when the application is about to terminate.
Save data if appropriate.
See also applicationDidEnterBackground:.
*/
}
- (void)dealloc
{
[_window release];
[rootController release];
[excerciseNavController release];
[__managedObjectContext release];
[__managedObjectModel release];
[__persistentStoreCoordinator release];
[super dealloc];
}
- (void)saveContext
{
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil)
{
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error])
{
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
*/
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
}
#pragma mark - Core Data stack
/**
Returns the managed object context for the application.
If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
*/
- (NSManagedObjectContext *)managedObjectContext
{
if (__managedObjectContext != nil)
{
return __managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil)
{
__managedObjectContext = [[NSManagedObjectContext alloc] init];
[__managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return __managedObjectContext;
}
/**
Returns the managed object model for the application.
If the model doesn't already exist, it is created from the application's model.
*/
- (NSManagedObjectModel *)managedObjectModel
{
if (__managedObjectModel != nil)
{
return __managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"Curl" withExtension:#"momd"];
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return __managedObjectModel;
}
/**
Returns the persistent store coordinator for the application.
If the coordinator doesn't already exist, it is created and the application's store added to it.
*/
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (__persistentStoreCoordinator != nil)
{
return __persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:#"Curl.sqlite"];
NSError *error = nil;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
{
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
Typical reasons for an error here include:
* The persistent store is not accessible;
* The schema for the persistent store is incompatible with current managed object model.
Check the error message to determine what the actual problem was.
If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.
If you encounter schema incompatibility errors during development, you can reduce their frequency by:
* Simply deleting the existing store:
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]
* Performing automatic lightweight migration by passing the following dictionary as the options parameter:
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.
*/
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return __persistentStoreCoordinator;
}
#pragma mark - Application's Documents directory
/**
Returns the URL to the application's Documents directory.
*/
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
#end
RoutineViewController:
#import "RoutineTableViewController.h"
#import "AlertPrompt.h"
#import "Routine.h"
#import "CurlAppDelegate.h"
#implementation RoutineTableViewController
#synthesize tableView;
#synthesize eventsArray;
#synthesize managedObjectContext;
- (void)dealloc
{
[managedObjectContext release];
[eventsArray release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
-(void)addEvent:(NSString *)name
{
CurlAppDelegate *curlAppDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [curlAppDelegate managedObjectContext];
Routine *routine = (Routine *)[NSEntityDescription insertNewObjectForEntityForName:#"Routine" inManagedObjectContext:context];
NSManagedObject *newRoutineEntry;
newRoutineEntry = [NSEntityDescription insertNewObjectForEntityForName:#"Routine" inManagedObjectContext:context];
NSError *error = nil;
if (![context save:&error]) {
// Handle the error.
}
NSLog(#"%#", error);
[eventsArray insertObject:routine atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
CurlAppDelegate *curlAppDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [curlAppDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Routine" inManagedObjectContext:context];
[request setEntity:entity];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[context executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
// Handle the error.
}
[self setEventsArray:mutableFetchResults];
[mutableFetchResults release];
[request release];
UIBarButtonItem * addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(showPrompt)];
[self.navigationItem setLeftBarButtonItem:addButton];
[addButton release];
UIBarButtonItem *editButton = [[UIBarButtonItem alloc]initWithTitle:#"Edit" style:UIBarButtonItemStyleBordered target:self action:#selector(toggleEdit)];
self.navigationItem.rightBarButtonItem = editButton;
[editButton release];
[super viewDidLoad];
}
-(void)toggleEdit
{
[self.tableView setEditing: !self.tableView.editing animated:YES];
if (self.tableView.editing)
[self.navigationItem.rightBarButtonItem setTitle:#"Done"];
else
[self.navigationItem.rightBarButtonItem setTitle:#"Edit"];
}
-(void)showPrompt
{
AlertPrompt *prompt = [AlertPrompt alloc];
prompt = [prompt initWithTitle:#"Add Workout Day" message:#"\n \n Please enter title for workout day" delegate:self cancelButtonTitle:#"Cancel" okButtonTitle:#"Add"];
[prompt show];
[prompt release];
}
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex != [alertView cancelButtonIndex])
{
NSString *entered = [(AlertPrompt *)alertView enteredText];
if(eventsArray && entered)
{
[eventsArray addObject:entered];
[tableView reloadData];
[self addEvent];
}
}
}
- (void)viewDidUnload
{
self.eventsArray = nil;
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [eventsArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellEditingStyleDelete reuseIdentifier:CellIdentifier] autorelease];
Routine* myRoutine = [self.eventsArray objectAtIndex:indexPath.row];
cell.textLabel.text = name;
return cell;
}
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the managed object at the given index path.
NSManagedObject *eventToDelete = [eventsArray objectAtIndex:indexPath.row];
[managedObjectContext deleteObject:eventToDelete];
// Update the array and table view.
[eventsArray removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
// Commit the change.
NSError *error = nil;
if (![managedObjectContext save:&error]) {
// Handle the error.
}
}
}
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/
}
#end
In your addEvent: method you insert two new Routine objects and save them but then you never do anything else with them. You don't set their attributes and you don't save the context after you do. Right now, you are doing nothing more than filling up the context with blank objects.
You need to create the objects, change their attribute/property values and only then save the context.
I have developed a core data model for my application. I need to display the saved data into a table view. For my app I have selected split view controller. I am writing down my codes below. Please help me in this regard and write me the code that needs to be added. This is very important as my continuation in my company depends on this.
#import "RootViewController.h"
#import "DetailViewController.h"
#import "AddViewController.h"
#import "EmployeeDetailsAppDelegate.h"
/*
This template does not ensure user interface consistency during editing operations in the table view. You must implement appropriate methods to provide the user experience you require.
*/
#interface RootViewController ()
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath;
#end
#implementation RootViewController
#synthesize detailViewController, fetchedResultsController, managedObjectContext, results, empName;
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
results = [[NSMutableDictionary alloc]init];
[results setObject:empName.text forKey:#"EmployeeName"];
[self.tableView reloadData];
[super viewDidLoad];
}
/*
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
*/
/*
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
*/
/*
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
}
*/
/*
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
}
*/
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Ensure that the view controller supports rotation and that the split view can therefore show in both portrait and landscape.
return YES;
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [[managedObject valueForKey:#"EmployeeName"] description];
}
#pragma mark -
#pragma mark Add a new object
- (void)insertNewObject:(id)sender {
AddViewController *add = [[AddViewController alloc]initWithNibName:#"AddViewController" bundle:nil];
self.modalPresentationStyle = UIModalPresentationFormSheet;
add.wantsFullScreenLayout = NO;
[self presentModalViewController:add animated:YES];
[add release];
}
#pragma mark -
#pragma mark Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [[managedObject valueForKey:#"EmployeeName"] description];
return cell;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the managed object.
NSManagedObject *objectToDelete = [self.fetchedResultsController objectAtIndexPath:indexPath];
if (self.detailViewController.detailItem == objectToDelete) {
self.detailViewController.detailItem = nil;
}
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
[context deleteObject:objectToDelete];
NSError *error;
if (![context save:&error]) {
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
*/
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
}
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// The table view should not be re-orderable.
return NO;
}
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Set the detail item in the detail view controller.
NSManagedObject *selectedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
self.detailViewController.detailItem = selectedObject;
}
#pragma mark -
#pragma mark Fetched results controller
- (NSFetchedResultsController *)fetchedResultsController {
if (fetchedResultsController != nil) {
return fetchedResultsController;
}
/*
Set up the fetched results controller.
*/
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Details" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"EmployeeName" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:#"Root"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
return fetchedResultsController;
}
#pragma mark -
#pragma mark Fetched results controller delegate
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
}
- (void)dealloc {
[detailViewController release];
[fetchedResultsController release];
[managedObjectContext release];
[super dealloc];
}
#end
//
// AddViewController.m
// EmployeeDetails
//
// Created by Dipanjan on 15/02/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "AddViewController.h"
#import "EmployeeDetailsAppDelegate.h"
#import "RootViewController.h"
#implementation AddViewController
#synthesize empName;
#synthesize empID;
#synthesize empDepartment;
#synthesize backButton;
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
/*
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization.
}
return self;
}
*/
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/
-(void)saveDetails{
EmployeeDetailsAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSManagedObject *newDetails;
newDetails = [NSEntityDescription insertNewObjectForEntityForName:#"Details" inManagedObjectContext:context];
[newDetails setValue:empID.text forKey:#"EmployeeID"];
[newDetails setValue:empName.text forKey:#"EmployeeName"];
[newDetails setValue:empDepartment.text forKey:#"EmployeeDepartment"];
empID.text = #"";
empName.text = #"";
empDepartment.text = #"";
NSLog(#"%#........----->>>...", newDetails);
NSError *error;
[context save:&error];
[self dismissModalViewControllerAnimated:YES];
}
-(void)findDetails {
EmployeeDetailsAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"Details" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
[request setEntity:entityDesc];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(EmployeeName = %#)", empName.text];
[request setPredicate:pred];
NSManagedObject *matches = nil;
NSError *error;
NSArray *objects = [context executeFetchRequest:request error:&error];
if ([objects count] == 0) {
}
else {
matches = [objects objectAtIndex:0];
empID.text = [matches valueForKey:#"EmployeeID"];
empDepartment.text = [matches valueForKey:#"EmployeeDepartment"];
}
[request release];
[self dismissModalViewControllerAnimated:YES];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Overriden to allow any orientation.
return YES;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
self.empName = nil;
self.empID = nil;
self.empDepartment = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[empID release];
[empName release];
[empDepartment release];
[super dealloc];
}
#end
Please let me know the answer as soon as possible.
#Dipanjan there is a core data tutorial in the devlopers document of X-Code and here it is coreDataBooks and its a best one try to take help from there in order to display the data in UITableView have a look at NSFetchedResultsController method.
http://www.bukisa.com/articles/180100_iphone-core-data-tutorial-part-1
http://mobile.tutsplus.com/tutorials/iphone/iphone-core-data/
Good Luck!
You need to fetch the data from the data using NSFetchResult. I guess you are doing it in the findDetails method, but where are you calling that method? You need to call that method to fetch the data, and then try to reload the table
Let me try to explain what I have on view and what's I'm trying to accomplish. I have a viewcontroller with two UIPickerView's in it. Each UIPickerView is connected via IFB. Everything works great but I'm trying to reload the data on one picker depending on which selection of another picker.
.m file
- (void)viewDidLoad
{
[super viewDidLoad];
pickerViewArray = [[NSMutableArray alloc] init];
[pickerViewArray addObject:#"Name 1"];
[pickerViewArray addObject:#"Name 2"];
[pickerViewArray addObject:#"Name 3"];
[pickerViewArray addObject:#"Name 4"];
[pickerViewArray addObject:#"Name 5"];
pickerViewArray2 = [[NSMutableArray alloc] init];
[pickerViewArray2 addObject:#"Phone 1"];
[pickerViewArray2 addObject:#"Phone 2"];
[pickerViewArray2 addObject:#"Phone 3"];
[pickerViewArray2 addObject:#"Phone 4"];
[pickerViewArray2 addObject:#"Phone 5"];
}
}
- (void)pickerView:(UIPickerView *)aPickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if([[pickerViewArray2 objectAtIndex:row] isEqual:#"Phone 2"]){
[picker2 reload];
}
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)aPickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)aPickerView numberOfRowsInComponent:(NSInteger)component {
return [pickerViewArray count];
}
- (NSString *)pickerView:(UIPickerView *)aPickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [pickerViewArray objectAtIndex:row];
}
Edit: to fix the problem I was having just add the array to each aPickerView i.e. titleForRow etc.
The reload method does just that - reloads the existing data. You need to move the logic that you have in viewDidLoad into titleForRow and numberOfRowsInComponent so that once the first picker has been actioned, the correct data can be returned. At the moment you load something different into pickerViewArray2 only at viewDidLoad, and that won't be re-run by your reload method.