在 SwiftUI 文档应用程序中,如何从函数中保存文档

问题描述

当前版本的 Xcode(版本 12.5.1)为适用于 macOS 的基于文档的应用程序提供模板,提供以下文档模型:

struct MyDocument: FileDocument {
    var text: String

    init(text: String = "Hello,world!") {
        self.text = text
    }

    static var readableContentTypes: [UTType] { [.exampleText] }

    init(configuration: ReadConfiguration) throws {
        guard let data = configuration.file.regularFileContents,let string = String(data: data,encoding: .utf8)
        else {
            throw CocoaError(.fileReadCorruptFile)
        }
        text = string
    }
    
    func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
        let data = text.data(using: .utf8)!
        return .init(regularFileWithContents: data)
    }
}

我想向这个结构添加一个方法,将我的文档传递给外部程序,并在这样做之前保存文档:

func passMyDocumentToProgram() {
    // Save document
    // Pass document to external program
}

问题是我不知道如何保存这样的文档。

生成的应用程序(从模板构建)提供了保存文档的功能(在菜单栏中),所以我应该以某种方式调用这个现有功能。

据我了解,fileWrapper 中的 MyDocument 方法返回一个 FileWrapper,其中有一个 write() 方法可以用来保存文档;但是,fileWrapper 方法需要一个 WriteConfiguration,我不知道如何创建它。 WriteConfiguration 的文档非常稀少,我在网上找不到任何有用的东西。

更新。更好的问题是如何触发我的文档应用程序自动保存?

我发现我可以用 FileWrapper(regularFileWithContents: data).write( ... ) 之类的东西保存我的文档,但这是个坏主意,因为您的应用程序会给您一个错误,提示外部程序修改了文件。

使用 FileDocument 协议编写的 SwiftUI 文档应用程序会在某些事件上自动保存其文档,例如(取消)聚焦窗口,所以我想知道是否有办法触发这样的自动- 以编程方式保存。

解决方法

按照与 https://stackoverflow.com/a/68331797/16524160 类似的过程,我们可以尝试获取 Save... 菜单项使用的实现。看着

let menu = NSApp.mainMenu!.items.first(where: { $0.title == "File" })!
let submenu = menu.submenu!.items.first(where: { $0.title == "Save…" })!
submenu.target // nil
submenu.action // saveDocument:

我为 MyDocument 想出了以下方法:

func save() {
    NSApp.sendAction(#selector(NSDocument.save(_:)),to: nil,from: nil)
}

注意 saveDocument 已重命名为 save。根据我的理解,这会尝试将 save() 选择器发送到可以对其做出反应的键窗口中的第一个对象。在我的例子中,关键窗口将包含用户正在编辑的文档,因此这将保存文档。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...