欢迎关注微信公众号「Swift 花园」
watchOS 应用
相比 macOS,iOS 和 tvOS ,watchOS (目前为止) 并非是完全独立的平台,一定程度上依赖配对的 iPhone 。
watchOS 6.0 之后,watch app 可以独立发布和安装,也就说,应用生态上可以独立了。但是,某些功能要想发挥最大的效用,还要借助 iPhone 设备的计算能力。毕竟,后者目前还是要强大很多。可以这么理解,当需要用到 watch 本身不具备的硬件能力时,如视频拍摄,你仍可以把 watch 视为控制器。这个跟人们看待早期智能手表的视角一致。
Watch app 和扩展
watchOS app 跟 iOS app 最显著的差异是前者被严格的分成了两部分。第一部分称为 Watch app —— 有点混淆对吧?正常理解,两部分加起来才是一个完整的 app 。但字面上,这个主要由 UI 构成的部分就叫 Watch app ,所以我们干脆以 UI 来代表,第二个部分是 WatchKit 扩展。两部分有各自独立的数据容器,如果需要共享容器中的文件,需要用到 App Groups 。
watch OS 6 引入 SwiftUI 后,情况变得有些复杂。因为 SwiftUI 中,UI 即代码。原来的 watch app 部分只有一个 hosting view 。
这些年 watchOS 的变化
watchOS 1 中,app UI 运行在 watch 上,但扩展运行在 iPhone 上。扩展可以很容易地与设备上的其他 iOS app 通信,但扩展和 watch UI 之间的通信是设备间的,因此整个 app 运行很慢。
watchOS 2 中,扩展被移到了 watch 上。watch app 和 iOS app 通信需要借助 WatchConnectivty framework 。因为扩展处于 watch 上,所以能用到 SDK 自然变少了。当然,后来各种缺失的 SDK 也被陆续添加到 watchOS 中。
watchOS 4 中,扩展和 UI 被合为一个进程运行。当然,这一点对开发者来说相对无感,唯一的效果是 app 运行的更快了。
watch OS 5 以前,WatchKit app 需要依赖 iPhone 的连接来完成大部分通信。它只能连接 iPhone 连接过的 “已知 Wi-Fi 网络” 。watch OS 5 引入了连接全新 WiFi 网络的能力。
在 watch OS 5 及之前的版本,watch app 总是要求有一个伴生的 iOS app 。watch app 是内置在 iOS app bundle 中,它的安装也是通过先安装 iOS app ,再间接下载到 watch 上来完成的。最近的 watch OS 6 ,watch app 真正意义上宣布独立。你既可以采用之前的 iOS app + watch app 的方式, 也可以只开发独立的 watch app 。watch app 不再是内置在 iOS app 中,两者被分隔在各自平台的 App Store 发布。因此,对于因特网的连接方式,最新的建议是 借助 URLSession ,CloudKit 等直接下载数据到 watch ,只有在真的需要跟 iPhone 交换数据时才用到 WatchConnectivity 。
多于一个用户接口
iOS app 通常有一个主要的用户入口。人们想到 iOS app 的时候,通常想到的是主界面上的图标。当然,也有各种扩展可以访问 app 的不同部分,但是通常被认为是主 app 的附属。你使用 app 的主要姿势是打开主 app 。
来到 watchOS ,情况大不相同。主 UI ,根据你的用例,很有可能不是最常被使用的部分。其主要原因在于 iPhone 和 Apple Watch 完全不同的交互模式。你不可能像在 iPhone 上那样在 watch 的屏幕上花很长的时间浏览内容吧?很显然,那很不舒服。
对于 watchOS ,Apple 一直重复的关键词是 glances 或者说 glanceable 。期望的 app 交互方式是:抬起手腕,看表,做一两个点击(或者甚至都不点击),或者转一下数字表冠,然后放下手腕,回到现实。这一系列动作的平均时间是以秒计的。实际上,建议是在 2 秒内让用户找到目标信息 (glanceable) 或者执行动作 (actionable) 。
如果你用过 watchOS app ,你应该知道通过主 app 找到目标信息需要一点技巧。首先,你要在主屏上那一堆六边形网格中找到 app ,然后点击,等待加载,然后在 app 的不同屏之间寻找你要的东西。基于此,也取决于你的 app 类型,极有可能你的主 UI 只会偶尔被用到。 WatchKit app 实际上提供了一些其他的入口来交互,它们可能更重要。
Notification
通知实际上是 watch 的一个绝佳的应用场景。花不到一秒的时间看一眼手表,比从口袋里掏出手机来省事不少吧?许多人会告诉你,他们戴 watch 的主要用途就是看通知。
但是,通知用的好不好,对不对,主要还是取决于你的 app 类型,通知的目的。比如,你的目的是不定期的通知用户某些事情发生了,通知可以是你的 app 很重要的一部分。典型的,提醒事项 app 。
watchOS 上通知的 UI 有三种变体:
- 只有预制的静态信息
- 非交互式的动态信息
- 可交互的动态信息,watchOS 5 引入
watch OS 6 允许推送绕过 iPhone ,只到达 Apple Watch 的远程通知。
Glances / Dock
watchOS 1 开始,引入了一种被叫做 glance 的界面,卡片式,可点击,水平滚动。借助 storyboard 上单独的场景构建。
watchOS 3 开始,glance 被废弃,由 dock 取代,后者是通过按压表侧的长按钮访问。它的工作方式和 glance 相似,但是卡片的外观是基于主 app 的实际 UI (类似 iOS 上的体验),通过系统对 app 生命周期某些节点的快照来实现。当你完成滚动,选择了某个 app 后,系统会唤醒这个 app ,不久之后这个 app 实际的 live 视图会更新 dock 的静态图片。
watch OS 4 之后,dock 变成竖向滚动,跟 iOS 的体验更相似。
Complications
“Complications“ 是 Apple 给表盘上的各种 widget 取的一个比较有逼格的名字。
Complications 有很多不同的家族,为不同的表盘设计 —— 圆形的,矩形的,小的,大的。这些 complictions 的共同点是展示信息的空间极其有限,一直可见(激活状态),因此需要保持最新状态。
你可以想象,complication 的特点是不可能通过让 app 持续运行在后台,并且完全访问表盘的方式来实现的。因为这样做电池撑不住。
Apple 的解决方案是你需要周期性的提前提供一个包含给定时间范围的 timeline 数据给 complication 用于显示。系统存储这份数据,到时间点了自动切换到正确的状态。你不能在 complication 里随意显示内容 —— 你只能从给定的 complication 家族中选择预先定义好的模板,然后填充一些精心准备的,允许系统在必要时简化以便适配可用空间的数据。
这里面的一个挑战是:如何找出有用的东西,填充到这么小的空间里 —— 同时这也是一个能简化工作的约束,因为你只有有限的选项。
Apple 一开始就说了,complications 只对部分 app 有意义 —— 因而并非每个 app 都有一些关键信息,可以展示为一个数字或者一行文本。不过,从 watchOS 3 开始,官方建议所有的 app 都实现一个 complication ,即便这个 complication 只是一个静态的启动器。(个人认为这个要求对用户的意义在于,用户可以在表盘上添加特定 app 的 complication ,仅仅作为启动器也是有价值的)。技术层面,系统可以针对当前表格的启动器,做一些优化,以便 app 启动更快。
Siri
最后一个入口就是 Siri 了, watchOS 5 以后,Siri 可以用于更多的用例,例如发消息,todo list 等等。