FileDocument
和 DocumentGroup
创建基于文档的应用程序?SwiftUI 附带了对基于文档的应用程序的支持,这些应用程序使用户可以创建,编辑和共享文本文件之类的文档。在 SwiftUI
中,我们可以使用两种主要类型:FileDocument
协议(用于定义应用程序中的文档的外观)以及 DocumentGroup
结构,该结构为我们提供了一个默认场景,允许用户创建,打开和保存文档。
创建自己的基于文档的应用程序需要四个步骤:
DocumentGroup
。Info.plist
文件以表明您要使用系统的文档浏览器。我们将从定义您的文档开始,对所有这些进行研究。某些文档类型会保存多个不同类型的文件,但是现在我们要说的是,我们仅支持纯文本,我们希望将这些文本直接读取并写入磁盘。
首先,在 Swift
文件的顶部添加 import UniformTypeIdentifiers
,以便引入统一的类型标识符,这是一种固定的方式来说明文档可以使用的数据类型。
现在添加此结构,定义一个简单的文本文件:
struct TextFile: FileDocument {
// 告诉系统我们仅支持纯文本
static var readableContentTypes = [UTType.plainText]
// 默认情况下,您的文档为空
var text = ""
// 创建新的空文档的简单初始化程序
init(initialText: String = "") {
text = initialText
}
// 此初始化程序加载以前保存的数据
init(configuration: ReadConfiguration) throws {
if let data = configuration.file.regularFileContents {
text = String(decoding: data, as: UTF8.self)
} else {
throw CocoaError(.fileReadCorruptFile)
}
}
// 当系统要将数据写入磁盘时,将调用此方法
func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
let data = Data(text.utf8)
return FileWrapper(regularFileWithContents: data)
}
}
请注意,如何在 fileWrapper(configuration:)
方法中将文本字符串转换为 Data
实例,然后使用 FileWrapper
保存它。 说文件应该存储在哪里不是我们的工作 – iOS会为我们负责。
我们的第二个任务是创建某种类型的编辑器区域,用户可以在其中编辑我们的文本。 这应该使用 @Binding
属性包装器,以便它更新 TextFile
结构中的文本,而不是保留其自己的本地副本:
struct ContentView: View {
@Binding var document: TextFile
var body: some View {
TextEditor(text: $document.text)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(document: .constant(TextFile()))
}
}
我们的第三步是编辑项目的主要 Swift
文件,使其包含 DocumentGroup
,该 DocumentGroup
提供了用于浏览,打开和创建文件的系统标准界面:
@main
struct YourAwesomeApp: App {
var body: some Scene {
DocumentGroup(newDocument: TextFile()) { file in
ContentView(document: file.$document)
}
}
}
如您所见,它告诉 iOS
如何创建新文件以及如何显示它们。
最后,我们需要向 Info.plist
添加一个新键,因此现在打开它,右键单击某个空间,然后选择“添加行”。 对于密钥名称,输入 Supports Document Browser
,确保“类型”设置为布尔值,然后将值设置为 YES
。
您的基于文档的应用已准备就绪。 如果您现在重新运行应用程序,您将看到标准的 iOS 文档选择器界面,如果按 +
,iOS 将创建一个新文件并在 ContentView
中打开该文件进行编辑。
如果是在 macOS 上进行保存会报错,如下报错信息
[OpenSavePanels] ERROR: Unable to display save panel: your app has the User Selected File Read entitlement but it needs User Selected File Read/Write to display save panels. Please ensure that your app's target capabilities include the proper entitlements.
这个时候需要编辑 Demo/macOS/macOS.entitlements
添加如下配置,到你的 macOS.entitlements
的配置中。
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.files.bookmarks.app-scope</key>
<true/>