简体   繁体   English

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

[英]How to open programmatically a document in a NSDocument macOS app?

I'm new to macOS programming and I created a NSDocument app project to learn this architecture. 我是macOS编程的新手,我创建了一个NSDocument应用程序项目来学习这个架构。

All works correctly, I can create a document, save it, and open one from Finder using standard UI controls. 一切正常,我可以创建一个文档,保存它,并使用标准UI控件从Finder打开一个文档。

I'm trying to save and open a document programmatically. 我正在尝试以编程方式保存和打开文档。 I implemented these two actions. 我实现了这两个动作。 Saving works fine, but read don't work. 保存工作正常,但读取不起作用。 Edit: I mean that the document window is not shown. 编辑:我的意思是没有显示文档窗口。

I would be very grateful if somebody could tell me what I'm doing wrong. 如果有人能告诉我我做错了什么,我将非常感激。

// 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")
    }
}

This seems to work. 这似乎有效。

Save the document: 保存文件:

@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")
    }
}

Open the document: 打开文档:

@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")
            }
        }
    }

}

(thanks to Willeke for the tips). (感谢Willeke的提示)。

NSDocument manages the display of a document from a URL. NSDocument管理来自URL的文档显示。 It's NSDocumentController that should be used to initiate the opening & saving of documents (although, as you have discovered, there's nothing stopping NSDocument from writing a copy of a document). 它应该用于启动文档的打开和保存的NSDocumentController (尽管如你NSDocument ,没有什么能阻止NSDocument 编写文档的副本)。

From the docs : 来自文档

NSDocumentController Creates and Manages Documents NSDocumentController创建和管理文档

An app's NSDocumentController object manages the documents in an app. 应用程序的NSDocumentController对象管理应用程序中的文档。 In the MVC design pattern, an NSDocumentController object is a high-level controller. 在MVC设计模式中,NSDocumentController对象是高级控制器。 It has the following primary responsibilities: 它具有以下主要职责:

  • Creates empty documents in response to the New item in the File menu 创建空文档以响应“文件”菜单中的“新建”项
  • Creates documents initialized with data from a file in response to the Open item in the File menu 创建使用文件中的数据初始化的文档, 以响应“文件”菜单中的“打开”项
  • Tracks and manages those documents 跟踪和管理这些文件
  • Handles document-related menu items, such as Open Recent 处理与文档相关的菜单项,例如“打开最近”

(my emphasis) (我的重点)

IF you want to use your own routine, you need to subclass NSDocumentController and put your open routine in there. 如果你想使用自己的例程,你需要NSDocumentController并将你的开放例程放在那里。 But it already has all of that logic, so really all you need to do is hook your button to the target of File -> Open, which will be func beginOpenPanel(completionHandler: @escaping ([URL]?) -> Void) in the default NSDocumentController . 但是它已经拥有了所有这些逻辑,所以你需要做的就是将你的按钮挂钩到File - > Open的目标,这将是func beginOpenPanel(completionHandler: @escaping ([URL]?) -> Void) in 默认的 NSDocumentController So there is no need to do so. 所以没有必要这样做。 Just read the NSDocumentController docs (linked above) 只需阅读NSDocumentController文档(上面链接)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 macOS(不是 iOS)上的 SwiftUI 中以编程方式从后台打开应用程序 window? - How to programmatically open the app window from the background in SwiftUI on macOS (not iOS)? 在macOS应用程序的打开的窗口中更改文档 - Change document in open window in macOS app macOS Swift:如何将NSDocument变量绑定到自定义NSView变量 - macOS Swift: How to bind NSDocument variable to custom NSView variable 如何以编程方式打开设置应用程序? - How to open settings app programmatically? 如何以编程方式从 FileProvider Extension (macOS) 打开文件 - How to programmatically open a file from FileProvider Extension (macOS) NSDocument:如何保存和恢复文档的窗口位置? - NSDocument: how do you save & restore a document's window position? 如何使用 swift 中的坐标以编程方式打开地图应用程序? - How to open maps App programmatically with coordinates in swift? 如何以编程方式检查并打开iOS 8中的现有应用程序? - How to Programmatically check and open an existing app in iOS 8? iOS | 如何以编程方式打开谷歌课堂应用程序 - iOS | how to open google classroom app programmatically Swift 在 macOS 中以编程方式打开新窗口 - Swift open new window programmatically in macOS
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM