系统环境
Mac OS 10.15.6
Xcode 12.4
创建watchOS App
在已有iOS项目中,新建Target,选择Watch App for iOS App
可以选择用Storyboard
构建UI,WatchKit App Delegate
管理生命周期,也可以选择用SwiftUI
构建UI,SwiftUI App
管理生命周期。本文选择前者。
完成创建后可以看到,除了我们创建的WatchKit App
,还自动创建了一个WatchKit App Extension
,目录结构如下
在WatchKit App Extension
中,默认勾选了Supports Running Without iOS App Installation
,即支持脱离iOS App单独运行。(苹果强烈建议)
如果需要依赖iOS App,去掉勾选状态,那么运行Watch App时,会自动打开对应模拟器并将iOS App安装到模拟器中。
启用Complication(默认启用了)
在我们创建Watch App时,Xcode已经默认为我们包含了Complication,如果没有,则需要自己手动启用。
步骤如下:
1、创建ComplicationController并遵循CLKComplicationDataSource
协议。
import Foundation
import ClockKit
class ComplicationController: NSObject, CLKComplicationDataSource {
func getCurrentTimelineEntry(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimelineEntry?) -> Void) {
// TODO: Finish implementing this required method.
}
}
2、在Extension的Assets目录中为静态占位符图像创建一个组。Assets.xcassets > Add Assets > watchOS > Watch Complication Placeholder
3、最后,在Extension > General > Complications Configuration
中设置Data Source Class
和Complication Group
。
Watch App 生命周期
代理对象通过实现WKExtensionDelegate
的代理方法来响应App的生命周期事件。
WatchKit通过实例化分配给WatchKit Extension
的Info.plist
文件中的WKExtensionDelegateClassName
键的类来自动创建您的委托对象。默认情况下,此类被命名为ExtensionDelegate
。然后,系统将委托对象分配给WKExtension单例的delegate属性。
Watch App 的状态及其影响
状态 | 描述 |
---|---|
没有运行 | watchOS应用程序未运行。用户尚未启动watchOS应用程序,或者系统已挂起然后清除了该应用程序。 |
不活跃 | watchOS应用程序在前台运行,但未从控件或手势接收操作;但是,它可能正在执行其他代码。新启动的应用程序通常在过渡到活动状态时仅短暂停留在此状态。过渡到此状态的活动应用程序应使其自身安静并准备过渡到后台。 |
活跃的 | watchOS应用程序在前台运行,并接收来自控件和手势的动作。这是屏幕上运行的应用程序的正常模式。 |
后台 | 系统为watchOS应用程序提供了少量的后台执行时间。在运行后台会话,执行后台任务以及挂起应用程序之前,系统会为应用程序提供后台执行时间。 由于系统可以清除挂起的应用程序而不会发出警告,因此请使用扩展代理的applicationDidEnterBackground()方法来保存重新创建应用程序当前状态所需的任何数据。如果需要,可以通过调用ProcessInfo类的performExpiringActivity(withReason:using:)方法来请求额外的后台执行时间。 |
暂停 | 该应用程序在内存中,但未执行代码。系统会挂起处于后台且没有任何待完成任务的应用程序。系统可以随时清除已暂停的应用程序,以便为其他应用程序腾出空间。该系统以静默方式清除已暂停的应用程序。挂起的应用程序不会唤醒,并且在系统清除它们之前不会收到任何通知。 系统尝试将常用的应用程序保留在内存中,以使其尽快恢复。具体而言,系统保留最近执行的应用程序,Dock中的所有应用程序以及当前活动表盘上具有复杂功能的所有应用程序。如果内存限制迫使系统清除这些应用程序之一,则一旦有更多内存可用,系统就会重新启动该应用程序。 |
Watch App架构
Watch App 是由 Watch App 和 WatchKit Extension 两个 bundle组成的,且 Watch App 包含了 Storyboard 和一些资源文件,Watch Extension包含了 Watch App的代码和另外的一些资源文件。另外,还可以通过WatchConnectivity
框架在 iOS和 WatchOS之间进行通信。
Watch App的生命周期变化
此图说明了 Watch App从启动开始的状态变化,以及WKExtensionDelegate
中对应的状态变化的协议方法,当然这与 iOS中AppDelegate
的协议方法是类似的。
A: applicationDidFinishLaunching
方法被调用。
B: applicationDidBecomeActive
或applicationWillResignActive
方法被调用。
C: applicationWillEnterForeground
或applicationDidEnterBackground
方法被调用。
WKInterfaceController的生命周期变化
WatchKit
中的WKInterfaceController
是Watch App
的主控制器,类似iOS
中的UIViewController
,声明周期也比较类似。但要理解它们本质上的区别,willActivate
和didDeactivate
只是在激活和失活时触发,与页面显示其实本质上本无关系。
awakeWithContext
:类似UIViewController
中的viewDidLoad
,可在此加载页面数据或初始化页面配置。
willActivate
:在准备展示界面时,系统会调用此方法(不保证界面在屏幕上或即将出现在屏幕上),不要在此方法中做执行界面的出事设置,可以做一些页面更新的事情。
didDeactivate
:系统会在清理WKInterfaceController
的过程中调用此方法,可以在此方法停用计时器或保存App状态信息。
didAppear
:当WKInterfaceController
显示时,系统会调用此方法,可以在此方法配置动画或其他与界面有关的任务。
willdisappear
:系统会在WKInterfaceController
即将从屏幕中移除时调用此方法,可以在此方法停止动画或执行其他与界面有关的任务。
用Storyboard构建watchOS应用界面
watchOS应用程序的用户界面使用了简化的,基于堆栈的布局模型。Xcode自动将元素分为水平和垂直堆栈,您可以通过修改元素的属性来微调布局。
在Storyboard中添加控件,Xcode会垂直堆叠它们,每个控件单独一行。
三个按钮垂直堆叠您也可以使用WKInterfaceGroup
创建水平或垂直堆栈,必要时,可以使用“嵌套组”来创建更复杂的布局。
使用属性自定义布局
您可以使用“属性”检查器微调界面元素的大小和布局。所有接口元素都具有以下属性:
Horizontal
配置项目在其容器提供的空间内的水平位置。
Vertical
配置项目在其容器提供的空间内的垂直位置。
Width & Height
确定系统如何计算对象的宽高。此属性具有三个可能的值:
Size to Fit Content
:根据对象的内容设置宽高。
Relative to Container
:将宽高设置为容器宽高的百分比。
Fixed
:设置指定宽高(以pt为单位)。
Groups还提供了其他选项来管理其内容:
Layout
指定Group
中项目的布局方向。可以是Horizontal
、Vertical
或Overlap
。
Insets
设置Group
的Insets
来设置Group
与其子元素之间的间隔(以pt为单位)。可以“自定义”其上、下、左、右边缘指定不同的值。
Spacing
设置组中子元素之间的间距(以pt为单位)。默认间距为2pt。
页面跳转方式
WatchKit支持三种样式在watchOS中的场景之间导航。
分页导航Paged navigation
一个分页的界面包含两个或多个独立的界面控制器,在任何给定时间显示一个。默认情况下,用户向左或向右滑动可在场景之间导航。屏幕底部的页面控件显示用户在页面中的当前位置。要切换到垂直分页,请在“属性”检查器中设置接口控制器的“页面方向”属性。
推出导航 Push navigation
推接口从单个根接口控制器开始。当前界面上的控件将新场景推送到屏幕上。同样,您可以弹出回到先前的控制器。推导航对于显示层次结构信息特别有用。例如,当用户从列表中选择一个项目时,您可以推送该项目的详细视图。
模态弹出 Modal Presentations
使用模式演示来中断用户的工作流,以请求输入或显示其他信息。模态表示本身可以由一个屏幕或包含多个屏幕的页面布局组成。
WatchKit还支持几个标准接口,用于收集输入或显示特定类型的信息。要显示这些接口,请使用下面列出的方法:
弹窗警告 Alert and action sheets
使用该方法可显示警报并使用标准界面请求用户输入。presentAlert(withTitle:message:preferredStyle:actions:)
文字输入 Text input
使用该方法接收来自用户的文本输入。此方法为控制器提供了相关的输入选项,其中可能包括预定义的短语,听写和涂抹。presentTextInputController(withSuggestions:allowedInputMode:completion:)
视频和音频播放 Video and audio playback
使用该方法播放音频和视频。presentMediaPlayerController(with:options:completion:)
录音 Audio recording
使用此方法可以显示标准的音频录制界面。presentAudioRecorderController(withOutputURL:preset:options:completion:)
PassKit通行证 PassKit passes
使用该方法显示用于将通行证添加到用户的Apple Watch的界面。presentAddPassesController(withPasses:completion:)
标准界面具有内置按钮,因此用户可以随时将其关闭。许多接口还具有dismiss方法,您可以使用该方法以编程方式关闭接口。界面处于活动状态时,您的应用无法直接控制与该界面的交互。将操作或完成处理程序用于与接口本身相关的任务。
参考资料
WatchOS开发教程之一: Watch App架构及生命周期
网友评论