macOS构建文档的NSDocument
macOS构建文档的NSDocument

macOS构建文档的NSDocument

NSDocument 是 macOS AppKit 中用于构建文档类型应用(document-based app)的核心类。可以提供:

1、文件读写管理(open/save)。

2、窗口控制。

3、撤销/重做系统。

4、文档状态跟踪(是否修改)。

5、自动保存、版本控制。

可以认为它是 macOS 上“带有打开、保存等菜单项的文档型应用”的基础结构,比如:

1、Pages、Numbers。

2、Xcode(.xcodeproj)。

3、Preview(.pdf)。

4、Sketch、Photoshop(.sketch, .psd)。

5、自定义的图像编辑器、代码编辑器等。

基本功能

1、read(from:):打开文件时读取数据。

2、data(ofType:):保存文件时提供数据。

3、makeWindowControllers():创建并管理视图控制器和窗口。

4、自动保存、版本控制:与 macOS 文件系统(NSFileCoordinator)集成,支持状态感知、自动保存等。

5、支持撤销/重做:内置 NSUndoManager 支持。

6、多文档支持:一次打开多个窗口、多个文件(如 Xcode)。

常用属性

1、fileURL:URL?类型,当前文档的文件路径,可能为 nil(尚未保存)。

2、isDocumentEdited:Bool类型,文档是否被修改(显示小圆点)。

3、undoManager:UndoManager?类型,撤销管理器。

4、windowControllers:[NSWindowController]类型,当前文档的窗口控制器列表。

5、autosavesInPlace:Bool类型,支持自动保存到原位置,默认 true。

6、hasUnautosavedChanges:Bool类型,是否有尚未保存的更改。

7、fileType:String?类型,当前文件的类型标识,如 public.plain-text。

常用方法

1、makeWindowControllers()

用于创建和添加文档的窗口控制器(视图 UI):

override func makeWindowControllers() {
    let wc = NSWindowController(windowNibName: "MyDocument")
    self.addWindowController(wc)
}

通常配合 Interface Builder .xib 或 SwiftUI 的 NSHostingController 来构建界面。

2、read(from:ofType:)

打开文件时系统调用,用于“读取数据”:

override func read(from data: Data, ofType typeName: String) throws {
    content = String(data: data, encoding: .utf8) ?? ""
}

可以将 Data 转为模型(字符串、JSON、图片、结构体等)。

3、data(ofType:)

保存文件时系统调用,用于“提供要保存的数据”:

override func data(ofType typeName: String) throws -> Data {
    return content.data(using: .utf8) ?? Data()
}

配合 read(from:) 和 data(ofType:) 实现文件打开与保存功能。

4、save(_ sender: Any?)

手动保存调用,一般不需要 override,除非要做特殊行为。

5、canClose(withDelegate:shouldClose:contextInfo:)

用于拦截用户关闭窗口时的行为(提示保存):

override func canClose(withDelegate delegate: Any, shouldClose selector: Selector?, contextInfo: UnsafeMutableRawPointer?) {
    if isDocumentEdited {
        // 弹窗提示保存
    } else {
        super.canClose(withDelegate: delegate, shouldClose: selector, contextInfo: contextInfo)
    }
}

6、autosavesInPlace

系统会自动调用该属性判断是否自动保存:

override class var autosavesInPlace: Bool {
    return true
}

7、updateChangeCount(_:)

当文档数据发生改变时,告知系统:

updateChangeCount(.done)

标记文档“已修改”,显示窗口标题上的小圆点。

8、fileWrapper(ofType:) 和 read(from:ofType:)

更复杂的文档结构可以使用 FileWrapper 处理目录、图像、多个数据文件等复合文档(如 Pages、Keynote)。

9、revert(toContentsOf:)

撤销文档内容到某个旧版本。

10、printOperation(withSettings:)

支持文档打印(可以自己构建一个 NSPrintOperation)。

文件支持

如果想要实现支持某种格式的文件,还需要配置Info.plist中的文件类型。

例如,支持 .txt 文件:

<key>CFBundleDocumentTypes</key>
<array>
  <dict>
    <key>CFBundleTypeName</key>
    <string>Text Document</string>
    <key>CFBundleTypeExtensions</key>
    <array>
      <string>txt</string>
    </array>
    <key>CFBundleTypeRole</key>
    <string>Editor</string>
    <key>NSDocumentClass</key>
    <string>MyDocument</string>
  </dict>
</array>

配置Info.plist文件后,右击txt文件,就可以选择mac应用打开。

总结

NSDocument主要负责文件读写、状态管理。可以实现打开时读取数据,保存时提供数据。

支持macOS自动保存和恢复机制,默认集成NSUndoManager。

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注