I'm using Core Data Undo Manager and view custom Undo Manager.
A Core Data with BackgroundTask. My project's core data stack is almost same with apple documents below. https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreData/Concurrency.html
When some contents are change(create update or delete), view's undo manager registerUndo and core data private managed context save(It makes undo task to its parents undo manager.)
So, the things I want to make is synchronize these two undo manager. Is there a best practice with these problems?
I'm just doing is that using Notification named 'NSUndoManagerDidUndoChange' handler calls undo like this.
func undoManagerDidUndo() {
DispatchQueue.main.async {
self.canvasView.undoManager?.undo()
self.setUndoButton()
}
}
func undoManagerDidRedo() {
DispatchQueue.main.async {
self.canvasView.undoManager?.redo()
self.setUndoButton()
}
}
func setUndoButton() {
guard let coreUndoManager = self.drawService.undoManager, let canvasUndoManager = self.canvasView.undoManager else { return }
DispatchQueue.main.async {
self.undoBtn.isEnabled = (coreUndoManager.canUndo && canvasUndoManager.canUndo)
self.redoBtn.isEnabled = (coreUndoManager.canRedo && canvasUndoManager.canRedo)
}
}
init() {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
self.mainContext = appDelegate.coreDataStack.mainContext
// self.mainContext!.undoManager = UndoManager()
privateMOC = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
privateMOC?.parent = mainContext
self.undoStackCount = 0
self.taskCount = 0
let nc = NotificationCenter.default
nc.addObserver(self, selector: #selector(self.contextDidChange), name: NSNotification.Name.NSManagedObjectContextObjectsDidChange, object: self.privateMOC)
nc.addObserver(self, selector: #selector(self.undoManagerDidUndo), name: NSNotification.Name.NSUndoManagerDidUndoChange, object: self.undoManager)
nc.addObserver(self, selector: #selector(self.undoManagerDidRedo), name: NSNotification.Name.NSUndoManagerDidRedoChange, object: self.undoManager)
}
It works almost well, but when the background task becomes bigger it does not sync well.
So, How can I sync these two different undo manager.