swift Apple Watch App 如何添加 Complication
建议每个 Apple Watch 应用都实现 Complication
, Complication
就是能显示在表盘上的一些应用组件,实现 Complication
之后系统会给予一些优先的权限,比如后台任务刷新:在没有实现 Complication
的时候系统1小时只会分配一次后台刷新,实现之后会实现多次。
添加 Complication 的官方说明: https://developer.apple.com/documentation/clockkit/adding_a_complication_to_your_watchos_app
当你在新建项目的时候没有勾选 complication
这一项,在后来又如何添加呢?
1. 新建一个实现了 CLKComplicationDataSource
的类
点击 fix
系统会自动添加这个 protocal
中必需的方法和变量。
2. 配置 complication
点击总项目,选择 target
为 extension
, 如图
再切到 general
标签,就会看到对应的 complication
的相关设置了
3. 实现代码
显示在表盘的 complication
需要通过实现 CLKComplicationDataSource
接口的类获取它需要的数据。
必须实现 CLKComplicationDataSource
中的两个方法,
一个是用于定义 complication 可获取的数据方向 getSupportedTimeTravelDirections
一个是给 complication
实时显示提供数据
注意: 因为 complication
显示是实时的,所以不要在提供数据的方法里写过量计算、需要大量时间运行的代码,如果需要显示一些大量计算的数据,一定要事先把数据处理好并存在一个地方,在用的时候直接取就可以了,不耗费时间。
还有其它一些可选的方法,具体可以查看 --> CLKComplicationDataSource
的 API <--
如,
// 提供时间轴中未来数据样本的方法:
func getTimelineEntries(for complication: CLKComplication, before date: Date, limit: Int, withHandler handler: @escaping ([CLKComplicationTimelineEntry]?) -> Void)
// 提供时间轴中过去数据样本的方法:
func getTimelineEntries(for complication: CLKComplication, after date: Date, limit: Int, withHandler handler: @escaping ([CLKComplicationTimelineEntry]?) -> Void)
4. 具体实现代码
比如我的
1) 定义 complication
可向 [前,后] 两个方向获取数据
func getSupportedTimeTravelDirections(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimeTravelDirections) -> Void) {
handler([.forward, .backward])
}
2) 给实时显示在表盘的 complication
提供显示的数据
这里需要说明一下:
a. 关于表盘插件的样式
所有可能表盘插件样式都在 CLKComplicationFamily
里列出来了,可以查看 CLKComplicationFamily 官方文档了解
b. 关于实现表盘数据的类
所有 template
样板都是从虚拟类 CLKComplicationTemplate
继承过来的,包括各种表盘插件所用的样式类,根据自己需要进行操作,如下图,都是:
func getCurrentTimelineEntry(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimelineEntry?) -> Void) {
var startLevel = 0
var timeDistance = 0.0
if let timeStart = defaults.object(forKey: Const.timeStart) as? Date {
startLevel = Int(defaults.double(forKey: Const.startLevel) * 100)
timeDistance = Date().distance(to: timeStart)
}
switch complication.family {
// 这里,对应不同的 family,也就是表盘中的插件样式的不同,需要返回对应样式的 template。
case .graphicCircular:
let template = CLKComplicationTemplateGraphicCircularStackText()
template.line1TextProvider = CLKSimpleTextProvider(text: "\(startLevel)")
template.line2TextProvider = CLKSimpleTextProvider(text: timeDistance.timeFormatString)
let entry = CLKComplicationTimelineEntry(date: Date(), complicationTemplate: template)
handler(entry)
case .graphicCorner:
// 不同 template 有不同的实现类
let template = CLKComplicationTemplateGraphicCornerStackText()
template.innerTextProvider = CLKSimpleTextProvider(text: "\(startLevel)")
template.outerTextProvider = CLKSimpleTextProvider(text: timeDistance.timeFormatString)
let entry = CLKComplicationTimelineEntry(date: Date(), complicationTemplate: template)
handler(entry)
case .graphicBezel:
let circle = CLKComplicationTemplateGraphicCircular()
circle.tintColor = Colors.magenta
let template = CLKComplicationTemplateGraphicBezelCircularText()
template.circularTemplate = circle
template.textProvider = CLKSimpleTextProvider(text: timeDistance.timeFormatString)
let entry = CLKComplicationTimelineEntry(date: Date(), complicationTemplate: template)
handler(entry)
default:
handler(nil)
}
}
5. 结果
获取应用中的两个数据,传递到表盘插件中
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。