0

I'm making a drawing app. With each tap some core data entities are created. The user can hit the undo button and those clicks are undone one at a time. This works fine.

The problem comes when some automated task is run. I have a button that creates a bunch of core data entities (draws some stuff by itself) in a child context and then saves the context so changes get reflected in the main context.

The problem is it doesn't matter how many times the user hits the task button, all changes are grouped into one single undo step.

To make it clear: He makes 5 tasks and then hits undo once and he is back at the beginning. But I want him to be able to undo each task one at a time.

I'm using UIManagedDocument and it's Core Data stack. So it's 2 contexts, one that writes to disk, and a child of it for general use, and then I create a child of the latter for background operations.

This is my code:

NSManagedObjectContext* childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
childContext.parentContext = self.document.managedObjectContext;
childContext.undoManager = self.document.undoManager;
[childContext performBlock:^{

    //a lot of things happen here, that generate many entities

    [childContext save:nil];

    [self.document.managedObjectContext performBlock:^{

        //completion stuff, update UI...

    }];
}];
Odrakir
  • 4,254
  • 1
  • 20
  • 52

1 Answers1

0

One idea is to enclose each block of code that you want to be undoable in its own block (with the same child context). Maybe start breaking it into two chunks and see if it works.

On second thought, I think that each save is not really saving but just pushing the changes up to the parent context. So my guess is that the parent context registers each child save as one undoable event. Maybe you could try saving more frequently and then see if these chunks can be undone.

Mundi
  • 79,884
  • 17
  • 117
  • 140
  • What you describe is exactly what I want: each child context save to be one undoable event. But it's not working like that. With each child save it groups all previous operations in one undoable event leaving the document back at how it was when opened. – Odrakir Mar 16 '13 at 09:10
  • So? Did you try the first strategy with creating separate contexts? – Mundi Mar 16 '13 at 13:06
  • If I understood you right, that's what I'm doing. Every block of code that I want to be undoable is inside its own performBlock function. It doesn't work. – Odrakir Mar 18 '13 at 16:53
  • Did you try allocating different contexts? Just curious. – Mundi Mar 18 '13 at 18:49
  • I'm sorry, I don't think I understand you. There is the main UIManagedDocument context (self.document.managedObjectContext) and then the child context I create in the code I posted. – Odrakir Mar 18 '13 at 19:31
  • Yes, my idea was to create more than one child context, one for each desired undo step. – Mundi Mar 18 '13 at 19:43
  • I am doing that. The child context is created everytime the user makes one of those tasks, so it's a different context everytime. – Odrakir Mar 18 '13 at 20:14