在 SwiftUI 文档应用程序中,如何从函数中保存文档
In a SwiftUI Document App, how to save a document from within a function
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
}
问题是我不知道如何保存这样的文档。
生成的应用程序(从模板构建)提供了保存文档的功能(在菜单栏中),因此我应该以某种方式调用此现有功能。
根据我的理解,MyDocument
returns 中的 fileWrapper
方法有一个 write()
方法可以用来保存文档;然而,fileWrapper
方法需要一个 WriteConfiguration
,我不知道如何创建它。 WriteConfiguration
的文档非常少,我无法在网上找到任何有用的东西。
更新。更好的问题是如何触发我的文档应用程序自动保存?
我发现我可以用 FileWrapper(regularFileWithContents: data).write( ... )
之类的东西保存我的文档,但这是个坏主意,因为你的应用程序会给你一个错误,说外部程序修改了文件。
使用 FileDocument
协议编写的 SwiftUI 文档应用程序会在某些事件上自动保存文档,例如(取消)聚焦 window,所以我想知道是否有办法我可以通过编程方式触发这样的自动保存。
按照与 类似的步骤,我们可以尝试获取 Save...
菜单项使用的实现。正在看
let menu = NSApp.mainMenu!.items.first(where: { [=10=].title == "File" })!
let submenu = menu.submenu!.items.first(where: { [=10=].title == "Save…" })!
submenu.target // nil
submenu.action // saveDocument:
我为MyDocument
想出了以下方法:
func save() {
NSApp.sendAction(#selector(NSDocument.save(_:)), to: nil, from: nil)
}
注意 saveDocument
已重命名为 save
。根据我的理解,这试图将 save()
选择器发送到键 window 中的第一个对象,该对象可以对其做出反应。在我的例子中,键 window 将包含用户正在编辑的文档,因此这将保存文档。
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
}
问题是我不知道如何保存这样的文档。
生成的应用程序(从模板构建)提供了保存文档的功能(在菜单栏中),因此我应该以某种方式调用此现有功能。
根据我的理解,MyDocument
returns 中的 fileWrapper
方法有一个 write()
方法可以用来保存文档;然而,fileWrapper
方法需要一个 WriteConfiguration
,我不知道如何创建它。 WriteConfiguration
的文档非常少,我无法在网上找到任何有用的东西。
更新。更好的问题是如何触发我的文档应用程序自动保存?
我发现我可以用 FileWrapper(regularFileWithContents: data).write( ... )
之类的东西保存我的文档,但这是个坏主意,因为你的应用程序会给你一个错误,说外部程序修改了文件。
使用 FileDocument
协议编写的 SwiftUI 文档应用程序会在某些事件上自动保存文档,例如(取消)聚焦 window,所以我想知道是否有办法我可以通过编程方式触发这样的自动保存。
按照与 Save...
菜单项使用的实现。正在看
let menu = NSApp.mainMenu!.items.first(where: { [=10=].title == "File" })!
let submenu = menu.submenu!.items.first(where: { [=10=].title == "Save…" })!
submenu.target // nil
submenu.action // saveDocument:
我为MyDocument
想出了以下方法:
func save() {
NSApp.sendAction(#selector(NSDocument.save(_:)), to: nil, from: nil)
}
注意 saveDocument
已重命名为 save
。根据我的理解,这试图将 save()
选择器发送到键 window 中的第一个对象,该对象可以对其做出反应。在我的例子中,键 window 将包含用户正在编辑的文档,因此这将保存文档。