[英]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
编写文档的副本)。
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.