Raphie Palefsky-Smith
Raphie Palefsky-Smith

Reputation: 515

Editing/Adding a Core Data entity with the same view?

First, let me explain what I'm trying to accomplish. I've got a master-detail application with a MasterViewController and a EditViewController. The MasterViewController contains an Add button and a table listing Core Data entities. When the user taps a table row or the Add button, the Edit view should pop up. I'm confused about how I should handle editing and adding differently.

Here's how I'm currently doing it: my app uses Storyboards, so I have editEntity and addEntity segues from Master to Edit. Both segues pass an entity to the EditViewController, but editEntity finds an existing entity based on the row tapped whereas addEntity creates a new one. Both segues set the isNew transient property on the entity.

The EditViewController doesn't know anything about Core Data--it simply edits the entity it's given. It in turn has done and cancel unwind actions. MasterViewController looks at the isNew property when considering cancel--if the entity is new, it deletes it, and if it already exists, it simply doesn't apply the changes.

This works, but it has a couple problems. Firstly, it seems a tad messy to add extra properties to the entity. Secondly, if the user closes the app on the Edit view while editing a new entity, that entity won't be deleted, which is certainly unexpected. Most of all, this seems like a problem that Core Data itself must have a solution to--I just don't know how. Thanks a bunch!

Upvotes: 3

Views: 404

Answers (1)

Tom Harrington
Tom Harrington

Reputation: 70956

The simplest improvement would be to replace the isNew flag on the entity description with a flag on your edit view controller. The edit VC might not know anything about Core Data, but it's OK to let it know if the object it's editing is new or pre-existing. Set the flag there, and have the master VC check the value before deciding how to proceed. Don't put this in your entity description, it's not data you need to keep around.

What I've done in this situation is create the new instance but don't insert it in the managed object context yet. Something like

NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Entity" inManagedObjectContext:[self managedObjectContext]];
NSManagedObject *myObj = [[NSManagedObject alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:nil];

Passing nil for the second argument when creating the instance gives you an instance that hasn't been inserted yet. Pass that to the edit view controller.

If the user taps on the save button, you can insert it later with something like:

if ([myObj managedObjectContext] == nil) {
    [[self managedObjectContext] insertObject:myObj];
}

Since the object hasn't been inserted, it has no managed object context, so checking that property tells you whether to insert it. Don't use the isInserted property here, it won't do what you need. Save changes in either case.

If the user taps "cancel", just don't insert it. The object gets deallocated just like any other object, and never makes it to the persistent store. Since you never inserted it, you don't need to bother deleting it.

Upvotes: 2

Related Questions