Search code examples
iosiphoneobjective-ccore-dataediting

Editing a Core Data Table View Entry With Overwriting the existing entry rather than creating a new entry


I have a Core Data based application with a table view controller; the user presses the plus button in the navigation bar and they're taken modally to a view controller where they can enter information into text fields. Pressing the save button saves this information Core Data and displays it in the Table view.

I've configured the app so that when I click on a cell, I'm taken to a view that has the information passed across successfully.

What I want to achieve is renaming a text field (for example, a name) and pressing Save updates THAT attribute in Core Data, rather than creating a brand new one with the same name and keeping the old one.

My save method in the editing view controller is:

- (IBAction)save:(id)sender
{
    NSManagedObjectContext *context = [self managedObjectContext];
    Transaction *transaction = [NSEntityDescription insertNewObjectForEntityForName:@"Transaction" inManagedObjectContext:context];
    Item *itemType = [NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:context];

    Person *enteredPerson = (Person *)[Person personWithName:self.editingNameTextField.text inManagedObjectContext:context];
    transaction.whoBy = enteredPerson;

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

Which calls:

+ (Person *)personWithName:(NSString *)name inManagedObjectContext:(NSManagedObjectContext *)context
{
    Person *person = nil;

    // Creating a fetch request to check whether the name of the person already exists
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Person"];
    request.predicate = [NSPredicate predicateWithFormat:@"name = %@", name];
    NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
    request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

    NSError *error = nil;
    NSArray *people = [context executeFetchRequest:request error:&error];
    if (!people)
    {
        // Handle Error
    }
    else if (![people count])
    {
        // If the person count is 0 then let's create it
        person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];
        person.name = name;
    }
    else
    {
        // If the object exists, just return the last object .
        person = [people lastObject];
    }
    return person; 

    /*
    for (Person *info in people)
    {
        NSLog(@"Names are: %@", person.name);
    }

     */
}

So when I click on a cell for Jack, it shows me all of Jack's information. I want to rename Jack to Jackie and have that update Core Data for ALL "Jackie's transactions" but with overwriting the Jack object, rather than keeping that and creating another called Jackie.

Any help on this would be appreciated!


Solution

  • To rename a person, you just have to fetch the object (using the old name) and then update the name attribute. For example:

    Person *person = [Person personWithName:oldName inManagedObjectContext:context];
    person.name = newName;
    

    All relationships to other objects (like transactions etc) are not modified by this.