Hi,大家好,我是姜友华,上一节我介绍iWriter的大概是什么样子,这一节开始我们来实现它。
一、新建macOS工程。
-
建立macOS工程与iOS工程一样。
选择macOS标签
二、 了解工程。
建好工程后,我们来了解一下工程。
1. 工程目录:
writer
-- writer
---- writerApp.swift // 程序入口,通过writerDocument加载文件到ContentView上显示。
---- writerDocument.swift // 新建,加载,保存文件。
---- ContentView.swift // 界面,这个只有一个文本编辑器。
---- Assets.xcassets
---- Info.plist
---- writer.entitlements
---- Preview Content
2. 运行工程。
初始状态的程序运行后程序,是一个极其简单的文本编辑器。虽然极其简单,但也是一个功能完备的程序。你完全可以用它进行写作,试试看非常神奇。
3. 工程代码。
- writerApp.swift,实例一个文档对象,然后传给视图。
@main
struct writerApp: App {
var body: some Scene {
DocumentGroup(newDocument: writerDocument()) { file in
ContentView(document: file.document)
}
}
}
- ContentView.swift,将文档对象的内容(这里是文字),显示在文本编辑器里。由于使用了
@Binding
,所以文本编辑器的内容会同步为文档对象的内容。
struct ContentView: View {
@Binding var document: writerDocument
var body: some View {
TextEditor(text: $document.text)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(document: .constant(writerDocument()))
}
}
- writerDocument.swift,负责文件的读写。
extension UTType {
static var exampleText: UTType {
UTType(importedAs: "com.example.plain-text")
}
}
struct writerDocument: 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)
}
}
-
文档格式配置。
文档格式配置
4. 需要注意的几个地方。
- writerApp.swift。
file in
里的file,为当前编辑的文件,带有当前文件的一些信息。 - ContentView.swift。通过
@Binding var document: writerDocument
的处理,TextEditor
失去焦点时,会引起写
. - writerDocument.swift。只是继承了
FileDocument
协议且读写的处理比较简单:读,转Data为字符串;写,转字符串为Data。不需要注意文件浏览器的处理。 - 文档格式配置只设置了文档(Document Types)与打开(Imported Type Identifiers)两部分,保存(Exported Types Identifiers)未设置。同时在
writerDocument.swift
里使用identifier
名来装载卸载自定义的格式。
三、更改存储样式。
1. 建立Model。
在更改存储样式之前,我们需要建立对应的数据模型。所以需要在-- writer
下建立Model
文件夹(New Gourp),及相关的文件(.swift)。
-- writer
---- model
------ Model.swift // 用于数据驱动。
------ Catalog.swift // 目录
------ Node.swift // 大纲节点
------ Sysbol.swift // 符号
------ Task.swift // 备忘录
------ Collect.swift // 收藏项
2. 自定义FileDocument。
我们需要自己定义一个文件格式,以适应我们的要求。
- 改
info.plist
设置自己的格式
- 改
writerDocument.swift
,使用自己设置的格式。
extension UTType {
static var writerFile: UTType {
UTType(importedAs: "com.muutr.writer-file")
}
}
struct writerDocument: FileDocument {
......
static var readableContentTypes: [UTType] { [.writerFile] }
......
}
- 运行试试。
-
点菜单的
可保存保存
,或control + s
。
保存的类型里有我们指定的iWriter File
的说明。
-
点菜单的
可打开打开
,或control + o
。
打开的文件浏览器里,选择Untitled
后,右则有iWriter File
的说明。
-
双击
Untitled
文件可打程序编辑。
双击Untitled
文件,会激活iWriter
程序,并用它打开Untitled
文件。 -
查看文件后缀
后缀正确
-
添加ICON.
Writer ICON
- Product → Clean Build Folder,再运行,变成了我们自已的程序,不错吧。
好吧,这一节就这些吧。我是姜友华,下次见。
网友评论