How do I implement undo with Core Data?

I can't get undo working with Core Data. Can anyone help?


I'm developing a Core Data/CloudKit iOS app in swift using the Master/Detail template. The Detail view all works as expected except for undo/redo.


Relevant code:

DetailViewController

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Establish an undo manager for the context.
        managedObjectContext?.undoManager = UndoManager()
    }

// MARK: - Bar Button Actions
    
    @IBAction func undoButton(_ sender: UIBarButtonItem) {
        if let context = managedObjectContext {
            print("DetailViewController.undoButton There are \(context.updatedObjects.count) objects registered with the context that have uncommitted changes")
            context.undo()
        }
        updateViewsFromModel()
    }
    
    @IBAction func redoButton(_ sender: UIBarButtonItem) {
        if let context = managedObjectContext {
            context.redo()
        }
        updateViewsFromModel()
    }


Example model function (ScoringPlay is a NSManagedObject defined in my Core Data schema):

    mutating func newScoringPlay() {
        if let currentContext = context {
            
            // Save the context before the change so the change will be available
            // for undo.
            save(currentContext) // Calls a helper method with a do/try/catch pattern to save the context
            
            let newScoringPlay = ScoringPlay(context: currentContext)
            currentContext.insert(newScoringPlay)

            // Set attributes and relationships ...
        }
    }



When I run the app in the simulator, add a new scoring play and then tap undo, the print line reports that there is an object registered with the context that has uncommitted changes. But, the following undo call appears to have no effect.


Thanks, CJ

It's the wrong way round, try:

Code Block
let newScoringPlay = ScoringPlay(context: currentContext)
// Set attributes and relationships ...
save(currentContext) // Calls a helper method with a do/try/catch pattern to save the context


No need to call insert, that's what the init with context does.
How do I implement undo with Core Data?
 
 
Q