I want to add a undo manager to a coredata backed iphone application. When the user tries to add a new object (by tapping on + button) I load a new modal viewcontroller and start a new undo group in viewDidLoad.
When the user presses Cancel button, I want to rollback the changes in cancelAction callback.
Queries:
Error Message:
* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '_endUndoGroupRemovingIfEmpty:: NSUndoManager 0x75415f0 is in invalid state, endUndoGrouping called with no matching begin
Sample Code:
// RootViewController.m
- (void) addAction {
// Load Modal View Controller to add new object
}
// AddViewController.m
- (void) viewDidLoad {
// Start nested undo group
[self.managedObjectContext processPendingChanges];
[self.managedObjectContext.undoManager beginUndoGrouping];
[self createModel];
}
- (void) cancelAction {
// Revert all changes
[self.managedObjectContext processPendingChanges];
[self.managedObjectContext.undoManager endUndoGrouping];
[self.managedObjectContext.undoManager undoNestedGroup];
...
}
- (void) saveAction {
// Save changes
}
Beginning with your specific questions - Yes, you can manually define the bounds of an undo operation using beginUndoGrouping and endUndoGrouping.
In this case, the undo operation should work whether or not groupsByEvent is set. This is because all the undo groups that are generated by the event loop are nested under your main open undo grouping started with beginUndoGrouping, and as long as you call undoNestedGroup directly after you call endUndoGrouping, it should work. If you are not using the event loop undo groupings, don't worry about it and set it to NO.
To make your changes permanent, close the undo group with endUndoGrouping and call save on your context. The processPendingChanges calls are not needed, and may cause issues in nested groups. If you want clear the undo operations, call removeAllActions on your undomanager after endUndoGrouping - this guarantees the changes will never be un-did.
Use breakpoints/nslog to make sure your begin/end calls are one for one.
If you want your cancel action to be like an 'undo button', you'll have to do the following:
Move beginUndoGrouping to viewWillAppear
Call endUndoGrouping in viewWillDisappear
re-open undo grouping at the end of your cancel action
re-open undo grouping at the end of your save action
Otherwise, if you leave it as is, make sure you close the dialog in your save and cancel actions, to avoid possibility of endUndoGrouping being called multiple times.
If you have any questions, please comment and I'll update.
Good luck!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With