Angad Manchanda
Angad Manchanda

Reputation: 183

Core Data Edit/Save Attributes in an Entity

I am struggling with the editing/saving in Core Data and need some help in this. I am using NSFetchedResultsController and have an entity named Golfer with attributes- first_name, last_name, email_id and others in Core Data. So, I know how to add and remove golfers from the database.

I am working on one view controller called ViewManager (kinda base view for all my classes) and it has 2-3 Custom UIViews inside it. I animate them in and out whenever I need them.

I add a golfer to the tableview, then on didSelectRow tableview method, I present my edit View inside the same ViewManager controller and try to update the textfields in the edit view using the following code, but it's updating at random indexes in the tableview and not working for me. Any help would be greatly appreciated.

- (IBAction)saveEditGolfersView:(id)sender
{
    AppDelegate * applicationDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext * context = [applicationDelegate managedObjectContext];

    // Retrieve the entity from the local store -- much like a table in a database
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Golfer" inManagedObjectContext:context];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entity]; 

    // Set the sorting -- mandatory, even if you're fetching a single record/object
    NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc] initWithKey:@"first_name" ascending:YES];

    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1,nil];
    [request setSortDescriptors:sortDescriptors];
    [sortDescriptors release]; sortDescriptors = nil;
    [sortDescriptor1 release]; sortDescriptor1 = nil;

    NSError * error;

    NSArray * objects = [context executeFetchRequest:request error:&error];

    for(int i = 0; i<[objects count]; i++)
    {
        Golfer * golfguy = [objects objectAtIndex:i];

        golfguy.first_name = mEditFirstName.text;
        golfguy.middle_name = mEditMiddleName.text;
        golfguy.last_name = mEditLastName.text;
        golfguy.email_id = mEditEmailField.text;
        golfguy.contactNumber = mEditContactNum.text;
        golfguy.picture = mEditPictureView.image;

        NSLog(@"name-%@", golfguy.first_name);
    }

    [request release]; request = nil;

     error = nil;
    [context save:&error];

    [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseOut

                     animations:^ {

                         mEditGolfersView.frame = CGRectMake(-480, mEditGolfersView.frame.origin.y, mEditGolfersView.frame.size.width, mEditGolfersView.frame.size.height);

                     }

                     completion:^(BOOL finished) {
                         mEditGolfersView.hidden = YES;

                     }];
}

Upvotes: 1

Views: 1029

Answers (1)

Sean Freitag
Sean Freitag

Reputation: 920

If I have read this code correct, then a call to -(IBAction)saveEditGolfersView:(id)sender will set all the Golfers with the exact properties, which I expect is not what you want.

I am not quite sure what the problem is, but I hypothesize that you need an NSPredicate to go along with your NSFetchRequest in order to change the correct Golfer(s).

Maybe I missed something, but this code says to me "hey, I'm going to load all of the Golfer in the database, order them by their first name, and then set all of their properties to the exact same text fields on this page". Just sounds like bad news...

To edit just one golfer, be sure to store the golfer you are editing in a property some where. Since you keep the managedObjectContext stored on the applicationDelegate, it will stay alive and thus keep your core data objects alive. That would avoid the expensive fetch that you are doing in the save view. If, however, you do not want to keep a reference to the golfer object, each NSManagedObject has an objectId, which is the identifier used by core data. You could use the objectId in a fetch predicate like so:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"objectId == %@", self.editingGolferObjectId];
[request setPredicate:predicate];

I would choose to keep reference to the object in your case, rather than the objectId

Upvotes: 1

Related Questions