【WWDC20】10039 - 如何用 SwiftUI 写一个独立的 App?

·  阅读 2786

作者:Damien,iOS 开发者。目前就职于携程。

Session: developer.apple.com/videos/play…

前言

通过此 Session 你将学习如何在 SwiftUI 中构建文档型 App, 通过 DocumentGroup API,以及 Pure SwiftUI AppScenes 组合,使你的 App 对文档管理的快速集成,例如文档浏览和 iCloud 文件浏览,而无需繁琐多余的工作。

概述

对于用户而言,访问和处理文档是最常用的操作。文档型 App 的功能也很明确:

  • 可以创建文档和打开文档
  • 用户可以编辑文档并将其保存到磁盘
  • 可以分享文件给另一个用户
  • 管理磁盘上的文件
  • 可以针对 iCloud 文件做增删查改操作

文字或许比较抽象,我们列举几个比较知名的 App 以便你快速理解什么是文档型 App

  • iOS / iPadOS 中的文件应用
  • Xcode & 系统邮件 App
  • 写作软件 Ulysses & 思维导图软件 MindNode

等等...

iOS/iPadOS 中的文件应用

早在 2017 年的 iOS 11 中,Apple 就发布了 Session 来讲述如何在 iOS 中构建文档型 App,具体可以查看 Session(Building Great Document-based Apps in iOS 11)。

然而在现在 (iOS 14) ,Apple 把它带到了 SwiftUI 中,并且提供了更简单、更优雅的方式让开发者接入,接下去,我们会带你一步步深入如何使用 SwiftUI 去开发一个文档型 App,最终我们会完成一个提供绘图并且具有保存绘图数据,打开绘图文件的功能 Mac / iPadOS 应用。

原理探索

创建项目

使用 Xcode 12 创建一个 Document App。我们这边可以选择多平台。因为我们要支持 iPadOS 和 MacOS

代码初探

创建成功后,你可以看到 Xcode 生成的模板代码结构

@main
struct TextEdit: App {
        var body: some Scene {
                DocumentGroup(newDocument: TextDocument()) { file in
                        TextEditor(text: file.$document.text)
                }
        }
}
复制代码

可以注意到,在 iOS 14 中,SwiftUI 代码发生了一些变化,如之前的 some View 变成了 some Scene,同时也多出了 App & DocumentGroup 这 2 个新东西。 别急,我会带你们一步步深入探索其中的变化。

首先,我们来看一张层级图:

App: SwiftUI 的新 API,App protocl 使我们能够轻松地用一个结构来替换 AppDelegate 和 SceneDelegate,该结构将管理我们的场景和应用生命周期。 Scene: SwiftUI 的新 API,它表示界面可以由不同的平台独立显示。 DocumentGroup: SwiftUI 的新 API,它可以自动管理 iOS,iPadOS 和 macOS 支持的,基于文档的场景的打开,编辑和保存。 在不同平台下 DocumentGroup的表现为:

  • iPadOS:

  • MacOS:

想了解更多 SwiftUI 的变化可以查看:WWDC 2020 - What's new in SwiftUI

好了,了解了这些概念之后,我们可以成功运行下 App (MacOS),看看效果

嗯,是一个具备基本能力的简易编辑器

让我们梳理下内部代码流程方便理解:

1、 App 文件中,使用了我们的新的 API App & @main 指定了程序的入口,最外层使用新 API Scene以便界面可以由不同的平台独立显示,并且使用了我们的新 API DocumentGroup 自动管理文档的场景的打开,编辑和保存,之后初始化了 ContentView 来进行 UI 展示

2、 在 ContentView 中, ContentView_Previews 不用关心,这是 SwiftUI 预览的入口,不是我们关心的重点,回过头看,ContentView 中,我们使用了 TextEditor(Swift iOS 14 新控件) 来展示了文档的文本,也就是之前我们 Demo 中的 Hello world 部分的 UI。

3、 ShapeEditDocument实现了协议FileDocument,来完成写入和打开文件的一系列操作。

FileDocumentFileDocument 是 iOS 14 中也是新增的 API。FileDocument协议是用于在文件内容之间进行序列化的文档模型定义。需要实现以下几个方法:

  • init(fileWrapper: FileWrapper, contentType: UTType) 在遵守 FileDocument 协议的对象被创建的时候,会被回调,可能是初始化,也有可能是打开某个文件时创建新的对象。
  • func write(to: inout FileWrapper, contentType: UTType) 需要被保存到磁盘的时候会被回调。
  • var readableContentTypes: [UTType] 返回可以识别 UTType。

UTType 是个什么呢?

UTType(Uniform Type) :是唯一标识抽象类型的字符串。它们可以被用来描述文件格式或内存中的数据类型,但也可以被用来描述其它种类实体的类型,比如目录、用量或包。

更进一步

上文我们实现了一个简单的文本编辑器,接下去,我们要完成一个自定义绘图软件。并完成保存和加载自定义文件格式的功能。我们来做一些改造:

1、 重构ShapeEditDocument的代码,使其支持我们自定义的格式来保存,我们这边使用 JSON 编码和解码来序列化我们的图形信息。 代码修改如下:

代码详解

我们修改了init(fileWrapper: FileWrapper, contentType: UTType)func write(to: inout FileWrapper, contentType: UTType)方法。在加载的方法中使用 JSON 解码,在写入磁盘的方法中我们使用了 JSON 编码。

2、 向系统注册自定义扩展类型

系统会维护一个列表,包含哪些类型的文件可以由哪些 App 去处理,我们需要实现自定义类型的加载和保存,所以我们需要向系统去注册我们可以处理哪些类型的文件。 修改如下:

代码详解

我们扩展了 UTType,自定义的 UTType:com.example.ShapeEdit.shapes。 之后重写var readableContentTypes: [UTType],使其返回了自定义类型。

注意:

UTType 有 ExportedType & ImportedType 之分。前者代表着我们的 App 拥有的专用类型向系统注册,后者标识是其他 App 拥有的类型,但是我们可以支持使用。 更多细节可以查看文档:

Defining File and Data Types for Your App

3、最后,将我们的 TextEditor替换为我们自定义绘图的Canvas对象即可(由于篇幅问题,展示不放出代码细节)

至此,我们的今天的 Session 的探索之路完美结束。

总结

在 iOS 14 中,Apple 给我们带来了更简洁的方式去创建文档型 App,区区几行代码即可实现功能强大的文档操作 App。希望开发者能基于此创造更大的价值。

推荐阅读

WWDC20 10041 - What's new in SwiftUI

WWDC20 10048 - 在 SwiftUI 中创建复杂功能

详解 WWDC 20 SwiftUI 的重大改变及核心优势

限时福利

这篇文章的内容来自于 《WWDC20 内参》。在这里给大家推荐一下这个专栏。

「WWDC 内参」系列是由老司机周报、知识小集合以及 SwiftGG 几个技术组织发起的。已经做了几年了,口碑一直不错。主要是针对每年的 WWDC 的内容,做一次精选,并号召一群一线互联网的 iOS 开发者,结合自己的实际开发经验、苹果文档和视频内容做二次创作。

今年一共有 213 个 Session 的内容。《WWDC20 内参》挑选了其中的 135 个 Session,专栏现已创作了 97 篇文章。目前正在优惠销售,只需要 29.9 元,十分优惠。

看了文章还不过瘾的朋友,抓紧订阅 《WWDC20 内参》 https://xiaozhuanlan.com/wwdc20 继续阅读吧~

关注我们

我们开通了公众号「老司机技术周报」,每期发布时公众号(LSJCoiding)会推送消息,欢迎关注。

分类:
iOS
标签: