iOS 中的 UndoManager 持久性

UndoManager persistence in iOS

我想在我的应用程序中实施 undo/redo 操作。 undo/redo 操作需要为每个文档而不是在 UIViewController 级别记录。所以我需要将 UndoManager 放在 class 实现自定义文档中。但是其中一个要求是 undo/redo 即使在应用程序重新启动时也应该是可能的,这意味着 UndoManager 必须是持久的。我们如何使 UndoManager 状态持久化?

据我所知,UndoManager 与您的数据模型没有直接关系,因此与您的应用程序状态(即数据模型状态)没有直接关系。 它仅允许您注册一些将以 undo/redo 方式改变数据模型的操作。 要实现持久性,在使用 UndoManager 时,您将不得不使用一些持久性存储(像 Core Data 或 Realm 这样的数据库,或者对于非常简单的状态,您可以使用 UserDefaults)。您必须执行您在 UndoManager 中注册的操作,以更新您选择使用的持久存储。 此外,您将不得不以某种方式跟踪数据库中的更改,以便您可以在应用程序启动之间恢复和注册它们。

我在网上找到的描述 Undo/Redo 操作注册的示例 - 取自此示例 - https://medium.com/flawless-app-stories/undomanager-in-swift-5-with-simple-example-8c791e231b87

//MARK:- Add/Remove Student : Undo/Redo Actions
// Register inverse Actions that automatically performs
extension StudentsListViewController {
  func addNewStudentUndoActionRegister(at index: Int){
    self.undoManager?.registerUndo(withTarget: self, handler: { (selfTarget) in
      selfTarget.removeNewStudent(at: index)
      selfTarget.removeNewStudentUndoActionRegister(at: index)
    })
  }
  
  func removeNewStudentUndoActionRegister(at index: Int){
    self.undoManager?.registerUndo(withTarget: self, handler: { (selfTarget) in
      selfTarget.addNewStudent(at: index)
      selfTarget.addNewStudentUndoActionRegister(at: index)
    })
  }
}

如您所见,操作只会更改状态,而 UndoManager 不会跟踪状态,只会跟踪操作...

一些个人看法: 对于复杂的逻辑和状态,我个人喜欢使用一些状态管理框架,比如 Redux(或者 Swift 等价的 ReSwift),在这种情况下,我可以轻松创建一个 Undo/Redo 动作。并且您可以轻松地记录应用程序生命周期中的状态,并将其记录到持久存储中,例如,使您的状态 Codable 并将其堆栈保存在存储中。 它有点像使用 UndoManager 的目的 - 但据我所知你不能将注册的操作保存到磁盘。