如何获取状态还原以还原macOS上的所有窗口/选项卡?

如何获取状态还原以还原macOS上的所有窗口/选项卡?,macos,cocoa,appkit,Macos,Cocoa,Appkit,我有一个非基于文档的macOS AppKit应用程序。它有一个由情节提要自动实例化的窗口。我对NSWindowController进行了子分类,并添加了一个override func newWindowForTab(uuSender:Any?)以启用选项卡栏上的+按钮。我的主视图控制器允许用户重命名选项卡标题,并且窗口标题设置为相同。这有点像Xcode选项卡重命名的工作方式 此外,我对NSWindow进行了子分类,并添加了一个RestorableStateKeyPath,以确保在应用程序重启时自

我有一个非基于文档的macOS AppKit应用程序。它有一个由情节提要自动实例化的窗口。我对
NSWindowController
进行了子分类,并添加了一个
override func newWindowForTab(uuSender:Any?)
以启用选项卡栏上的+按钮。我的主视图控制器允许用户重命名选项卡标题,并且窗口标题设置为相同。这有点像Xcode选项卡重命名的工作方式

此外,我对NSWindow进行了子分类,并添加了一个
RestorableStateKeyPath
,以确保在应用程序重启时自动恢复选项卡和窗口标题

这一切都很好

但只限于第一个标签。将加载主窗口,并自动设置选项卡和窗口标题

其他选项卡(窗口)不会恢复

关于我错过了什么使所有选项卡恢复的提示

我的
NSWindowController

class MyWindowController: NSWindowController {
    var subview: MyWindowController?

    @IBAction override func newWindowForTab(_ sender: Any?) {
        let story = self.storyboard
        let windowVC = story?.instantiateInitialController() as! Self

        window?.addTabbedWindow(windowVC.window!, ordered: .above)
        subview = windowVC

        windowVC.window?.orderFront(self.window)
        windowVC.window?.makeKey()
    }
}
我的
NSWindow

class MyWindow: NSWindow {
    override class var restorableStateKeyPaths: [String] {
       return [ "self.tab.title", "self.title" ]
    }
}

首先,您需要确保为您的用户启用了状态恢复,您可以通过转到“首选项->常规”并取消选中“退出应用时关闭窗口”来完成此操作

然后,您应该使用还原类来还原所有打开的窗口

基本上,如果一个NSWindow没有恢复类,它将不会在整个发布过程中被保留,这包括你的脚本加载窗口。在这种情况下,Cocoa将忽略所有窗口保留,因为您尚未为任何窗口定义恢复类,因此它将采用默认行为,即加载初始情节提要控制器

实现恢复类很简单,只需创建一个从NSObject继承并符合NSWindowRestoration的恢复类,然后实现它唯一需要的类型方法
restoreWindow(标识符:state:completionHandler)
如下:

class MyAppWindowRestoration: NSObject, NSWindowRestoration {
    
    static func restoreWindow(withIdentifier identifier: NSUserInterfaceItemIdentifier,
                              state: NSCoder,
                              completionHandler: @escaping (NSWindow?, Error?) -> Void) {
        // 1.- Retrieve and show the window
        // Retrieve a new instance of the only window
        let window = (NSStoryboard.main?.instantiateInitialController() as? NSWindowController)?.window
        
        // Call the completion handler with the window and no errors
        completionHandler(window, nil)
    }

}
然后,只需将该类指定为要还原的每个窗口上的窗口还原类,即可在加载窗口后在任何地方执行此操作:

window.restorationClass = MyAppWindowRestoration.self
不幸的是,苹果关于状态恢复的文档非常糟糕,所以如果您还有任何问题,请告诉我;)