Swift 如何在NSDocument macOS应用程序中以编程方式打开文档?

Swift 如何在NSDocument macOS应用程序中以编程方式打开文档?,swift,macos,nsdocument,Swift,Macos,Nsdocument,我是macOS编程新手,我创建了一个NSDocument应用程序项目来学习这种体系结构 所有工作正常,我可以创建一个文档,保存它,并使用标准UI控件从Finder打开一个 我正在尝试以编程方式保存和打开文档。我实施了这两项行动。保存可以很好地工作,但读取不起作用。编辑:我的意思是文档窗口不显示 如果有人能告诉我我做错了什么,我将不胜感激 // this seems to work because the document is created and I can open it with dra

我是macOS编程新手,我创建了一个NSDocument应用程序项目来学习这种体系结构

所有工作正常,我可以创建一个文档,保存它,并使用标准UI控件从Finder打开一个

我正在尝试以编程方式保存和打开文档。我实施了这两项行动。保存可以很好地工作,但读取不起作用。编辑:我的意思是文档窗口不显示

如果有人能告诉我我做错了什么,我将不胜感激

// this seems to work because the document is created and I can open it with drag and drop over the app
@IBAction func saveButtonPressed(_ sender: Any) {
    let directoryURL = FileManager.default.urls(for: .desktopDirectory, in: .userDomainMask).first // or .applicationSupportDirectory

    let docURL = URL(string:"MyFile.docuExperiments", relativeTo:directoryURL)

    if (try? document.write(to: docURL!, ofType: "com.myCompany.docuExperiments")) != nil {
    } else {
        print("An error occured")
    }
}

// the document window is not shown
@IBAction func loadButtonPressed(_ sender: Any) {
    let directoryURL = FileManager.default.urls(for: .desktopDirectory, in: .userDomainMask).first // or .applicationSupportDirectory

    let docURL = URL(string:"MyFile.docuExperiments", relativeTo:directoryURL)

    if (try? document.read(from: docURL!, ofType: "com.myCompany.docuExperiments")) != nil {
    } else {
        print("An error occured")
    }
}

NSDocument
管理URL中文档的显示。应该使用
NSDocumentController
来启动文档的打开和保存(不过,正如您所发现的,没有什么可以阻止
NSDocument
编写文档副本)

从:

NSDocumentController创建和管理文档

应用程序的NSDocumentController对象管理应用程序中的文档。 在MVC设计模式中,NSDocumentController对象是 高级控制器。其主要职责如下:

  • 创建空文档以响应“文件”菜单中的新项
  • 创建用文件中的数据初始化的文档,以响应 文件菜单中的打开项
  • 跟踪和管理这些文档
  • 处理 与文档相关的菜单项,例如“打开最近的文档”
(我的重点)

如果您想使用自己的例程,则需要将
NSDocumentController
子类化,并将打开的例程放在其中。但是它已经有了所有的逻辑,所以实际上你需要做的就是将你的按钮挂到File->Open的目标上,这将是
func beginpenpanel(completionHandler:@escaping([URL]?)->Void)
默认值中的NSDocumentController。因此,没有必要这样做。只需阅读
NSDocumentController
文档(链接在上面)

这似乎有效

保存文档:

@IBAction func saveButtonPressed(_ sender: Any) {
    let directoryURL = FileManager.default.urls(for: .desktopDirectory, in: .userDomainMask).first

    let docURL = URL(string:"MyFile.docuExperiments", relativeTo:directoryURL)

    if (try? document.write(to: docURL!, ofType: "com.myCompany.docuExperiments")) != nil {
    } else {
        print("An error occured")
    }
}
@IBAction func loadButtonPressed(_ sender: Any) {
    let documentController = NSDocumentController.shared()

    let directoryURL = FileManager.default.urls(for: .desktopDirectory, in: .userDomainMask).first

    let docURL = URL(string:"MyFile.docuExperiments", relativeTo:directoryURL)

    documentController.openDocument(withContentsOf: docURL!, display: true) {
        // completionHandler (NSDocument?, Bool, Error?)
        (document, documentWasAlreadyOpen, error) in
        if error != nil
        { print("An error occured")
        } else {
            if documentWasAlreadyOpen
            {
                print("documentWasAlreadyOpen: true")
            } else {
                print("documentWasAlreadyOpen: false")
            }
        }
    }

}
打开文档:

@IBAction func saveButtonPressed(_ sender: Any) {
    let directoryURL = FileManager.default.urls(for: .desktopDirectory, in: .userDomainMask).first

    let docURL = URL(string:"MyFile.docuExperiments", relativeTo:directoryURL)

    if (try? document.write(to: docURL!, ofType: "com.myCompany.docuExperiments")) != nil {
    } else {
        print("An error occured")
    }
}
@IBAction func loadButtonPressed(_ sender: Any) {
    let documentController = NSDocumentController.shared()

    let directoryURL = FileManager.default.urls(for: .desktopDirectory, in: .userDomainMask).first

    let docURL = URL(string:"MyFile.docuExperiments", relativeTo:directoryURL)

    documentController.openDocument(withContentsOf: docURL!, display: true) {
        // completionHandler (NSDocument?, Bool, Error?)
        (document, documentWasAlreadyOpen, error) in
        if error != nil
        { print("An error occured")
        } else {
            if documentWasAlreadyOpen
            {
                print("documentWasAlreadyOpen: true")
            } else {
                print("documentWasAlreadyOpen: false")
            }
        }
    }

}

(感谢Willeke提供的提示)。

不,不要将
NSDocumentController
子类化以打开文档。您是否将我的答案读到了最后?OP的问题是关于文件对话框,我指出没有必要这样做。然而,如果他想实现他写下的例行程序,那就是最好的地方。但他不需要这样做。将打开例程(按钮的操作方法)放在app委托中,而不是放在
NSDocumentController
的子类中。按原样使用NSDocumentController。您能比“读取不起作用”更具体一些吗?到底发生了什么?应该按
loadbutton
创建新文档对象还是重新加载现有文档对象?嗨,rob,文档窗口不显示。我将更新问题谢谢。你好,Willeke我的意图是打开一个已关闭的文档。使用
NSDocumentController
s
openDocument(内容为:display:completionHandler:)
打开。使用
NSDocument
s
saveToURL:ofType:forSaveOperation:completionHandler:
保存。