何时何地获取 Watch Complication 的数据
Where and When to get data for Watch Complication
在处理了几天的复杂问题后,对于按规定时间间隔发生的更新的更新过程,我有信心说出以下内容:
- 系统调用
requestedUpdateDidBegin()
- 在这里您可以确定您的数据是否已更改。如果没有,则您的应用程序无需执行任何操作。如果您的数据已更改,您需要调用:
reloadTimelineForComplication
如果您的所有数据都需要重置。
extendTimelineForComplication
如果您只需要将新项目添加到并发症时间线的末尾。
- 注意:如果您当天花费了过多的并发症时间预算,系统实际上可能会调用
requestedUpdateBudgetExhausted()
而不是 requestedUpdateDidBegin()
。这就是这个问题的原因。
- 如果您调用
reloadTimelineForComplication
,系统将调用getCurrentTimelineEntryForComplication
(以及获取数组的未来和过去变体,具体取决于您的时间旅行设置)
- 这是推测,因为我还没有测试过,但我相信如果你调用
extendTimelineForComplication
只会调用 getTimelineEntriesForComplication(... afterDate date: NSDate ...)
。
- 然后系统将调用
getNextRequestedUpdateDateWithHandler
,因此您可以指定您的并发症需要多长时间才能进行新的更新。
Apple的文档说的很清楚,不要太频繁的请求更新,或者在complication代码中做太多的处理,否则会耗尽你的时间预算,你的complication会停止更新。所以,我的问题是:您在何时何地进行更新?
对于上下文,我的场景是 URL,其中 return 数据每小时最多更改两次。
放置URL获取代码最明显的地方是func requestedUpdateDidBegin()
获取数据,存储它,如果没有变化,就return。如果有变化,则延长或重新加载时间线。
但是,URL 获取的成本可能很高。备选方案:
- 将代码放在 phone 应用程序上并通过
WCSession
发送,但如果用户关闭该应用程序,则更新将不再发生。
- 使用推送更新,但这不是网络应用程序,所以我没有地方可以发送它们。
- 显然,当用户与手表应用程序交互时,我会更新所有数据,但现在这意味着它只会在用户使用该应用程序时更新,这就不需要复杂化了。
还有别的地方吗?我可以在手表应用程序中使用不属于复杂功能的定期功能吗?获取复杂功能更新数据的正确位置在哪里?
编辑:El Tea (op) post在
上给出了一个很好的答案
这很有趣 question/problem,我一直想知道很多相同的东西!
在大多数情况下,当我处理一个新的复杂功能时,我似乎需要退后一步,看看我什么时候真的想要更新它。当设置 "end date" 时,"countdown" 复杂功能可以一次设置所有未来的时间线条目。当 APNS 通过时,显示 Web 服务当前状态的应用程序可以将相关数据存储在 NSUserDefaults
中。
如果您无法访问 APNS,不想 运行 您的 iOS 应用处于后台模式,并且不想从 Apple Watch 发出 HTTP 请求,我可以想到其他 2 个选项。
1) 安排本地通知。好的部分是你的 Apple Watch 应该运行didReceiveLocalNotification
,但不好的部分是用户会当您只是尝试在不中断的情况下检查状态时收到通知。
2) 在你的 reloadTimelineForComplication
方法中通过 sendMessage(_:replyHandler:errorHandler:)
向 iOS 发送消息,将 nil
设置为 replyHandler
尽快完成:
Calling this method from your WatchKit extension while it is active and running wakes up the corresponding iOS app in the background and makes it reachable.
您的 iOS 应用程序可以执行任何需要的网络请求,然后存储信息或将其推送到 Apple Watch。不幸的是,我不认为 watch 扩展程序会在您 运行 之前调用它 session.didReceive...
,但是您可以在下一次调用 requestedUpdateDidBegin
时访问数据。
正如我所说,我对同样的事情非常感兴趣,所以 post 回顾一些想法,也许我们可以在这里推断出一些最佳实践。
对于 watchOS 3,Apple 建议您不要使用并发症数据源 getNextRequestedUpdateDate
计划更新来更新您的并发症。
watchOS 2 的旧方法
requestedUpdateDidBegin()
实际上只是为了更新复杂功能而设计的。使您的复杂功能(和手表应用程序)保持最新通常不仅仅涉及重新加载时间线(并且异步检索数据永远不适合旧方法)。
watchOS 3 的新方式
更好的新方法是使用 background refresh app tasks. You can use a series of background tasks to schedule and handle 在后台唤醒您的应用程序扩展来:
获取新数据
- 使用WKWatchConnectivityRefreshBackgroundTask从phone获取数据,或者
- 使用WKURLSessionRefreshBackgroundTask从服务器下载数据
- 数据到达后更新您的模型,
- 从模型更新您的并发症(通过重新加载或延长时间线),最后
- 更新应用程序的停靠栏快照以显示停靠栏上的数据
任务完成后立即调用每个任务的setTaskCompleted
方法。
使用应用任务的其他好处
此设计的一个主要特点是手表扩展现在可以处理各种前景和背景场景,包括:
- 在 app/complication 启动时初始加载数据,
- 在后台更新数据,当扩展被后台任务唤醒时,
- 当用户从停靠栏恢复您的应用程序时,在前台更新数据。
Apple 建议您利用获得的每一个机会,无论您的应用程序是在前台还是后台,以使您的复杂功能、应用程序和停靠栏快照保持最新。
有什么限制吗?
每天可用任务总数除以扩展坞中的应用程序数量。 Dock 中的应用程序越少,您的应用程序可以使用的任务就越多。 Dock 中的应用程序越多,您可以使用的应用程序就越少。
如果您的并发症处于活动状态,您的应用每小时至少可以被唤醒四次。
如果您的并发症未激活,您的应用保证至少每小时被唤醒一次。
由于您的应用现在 运行 在后台运行,因此您需要高效快速地完成后台任务。
后台任务受限于 CPU 时间和允许的 CPU 使用量。如果您超过 CPU 时间(或在后台使用超过 CPU 的 10%),系统将终止您的应用程序(导致崩溃)。
了解更多信息
中介绍了更新手表应用程序的时间和原因的很好的介绍
具体而言,Keeping Your Watch App Up to Datesession涵盖了让您的复杂功能、应用程序和 Dock 快照保持最新所需的一切。
WatchBackgroundRefresh示例代码演示了如何使用WKRefreshBackgroundTask
在后台更新WatchKit应用程序。
在处理了几天的复杂问题后,对于按规定时间间隔发生的更新的更新过程,我有信心说出以下内容:
- 系统调用
requestedUpdateDidBegin()
- 在这里您可以确定您的数据是否已更改。如果没有,则您的应用程序无需执行任何操作。如果您的数据已更改,您需要调用:
reloadTimelineForComplication
如果您的所有数据都需要重置。extendTimelineForComplication
如果您只需要将新项目添加到并发症时间线的末尾。
- 注意:如果您当天花费了过多的并发症时间预算,系统实际上可能会调用
requestedUpdateBudgetExhausted()
而不是requestedUpdateDidBegin()
。这就是这个问题的原因。
- 在这里您可以确定您的数据是否已更改。如果没有,则您的应用程序无需执行任何操作。如果您的数据已更改,您需要调用:
- 如果您调用
reloadTimelineForComplication
,系统将调用getCurrentTimelineEntryForComplication
(以及获取数组的未来和过去变体,具体取决于您的时间旅行设置) - 这是推测,因为我还没有测试过,但我相信如果你调用
extendTimelineForComplication
只会调用getTimelineEntriesForComplication(... afterDate date: NSDate ...)
。 - 然后系统将调用
getNextRequestedUpdateDateWithHandler
,因此您可以指定您的并发症需要多长时间才能进行新的更新。
Apple的文档说的很清楚,不要太频繁的请求更新,或者在complication代码中做太多的处理,否则会耗尽你的时间预算,你的complication会停止更新。所以,我的问题是:您在何时何地进行更新?
对于上下文,我的场景是 URL,其中 return 数据每小时最多更改两次。
放置URL获取代码最明显的地方是func requestedUpdateDidBegin()
获取数据,存储它,如果没有变化,就return。如果有变化,则延长或重新加载时间线。
但是,URL 获取的成本可能很高。备选方案:
- 将代码放在 phone 应用程序上并通过
WCSession
发送,但如果用户关闭该应用程序,则更新将不再发生。 - 使用推送更新,但这不是网络应用程序,所以我没有地方可以发送它们。
- 显然,当用户与手表应用程序交互时,我会更新所有数据,但现在这意味着它只会在用户使用该应用程序时更新,这就不需要复杂化了。
还有别的地方吗?我可以在手表应用程序中使用不属于复杂功能的定期功能吗?获取复杂功能更新数据的正确位置在哪里?
编辑:El Tea (op) post在
这很有趣 question/problem,我一直想知道很多相同的东西!
在大多数情况下,当我处理一个新的复杂功能时,我似乎需要退后一步,看看我什么时候真的想要更新它。当设置 "end date" 时,"countdown" 复杂功能可以一次设置所有未来的时间线条目。当 APNS 通过时,显示 Web 服务当前状态的应用程序可以将相关数据存储在 NSUserDefaults
中。
如果您无法访问 APNS,不想 运行 您的 iOS 应用处于后台模式,并且不想从 Apple Watch 发出 HTTP 请求,我可以想到其他 2 个选项。
1) 安排本地通知。好的部分是你的 Apple Watch 应该运行didReceiveLocalNotification
,但不好的部分是用户会当您只是尝试在不中断的情况下检查状态时收到通知。
2) 在你的 reloadTimelineForComplication
方法中通过 sendMessage(_:replyHandler:errorHandler:)
向 iOS 发送消息,将 nil
设置为 replyHandler
尽快完成:
Calling this method from your WatchKit extension while it is active and running wakes up the corresponding iOS app in the background and makes it reachable.
您的 iOS 应用程序可以执行任何需要的网络请求,然后存储信息或将其推送到 Apple Watch。不幸的是,我不认为 watch 扩展程序会在您 运行 之前调用它 session.didReceive...
,但是您可以在下一次调用 requestedUpdateDidBegin
时访问数据。
正如我所说,我对同样的事情非常感兴趣,所以 post 回顾一些想法,也许我们可以在这里推断出一些最佳实践。
对于 watchOS 3,Apple 建议您不要使用并发症数据源 getNextRequestedUpdateDate
计划更新来更新您的并发症。
watchOS 2 的旧方法
requestedUpdateDidBegin()
实际上只是为了更新复杂功能而设计的。使您的复杂功能(和手表应用程序)保持最新通常不仅仅涉及重新加载时间线(并且异步检索数据永远不适合旧方法)。
watchOS 3 的新方式
更好的新方法是使用 background refresh app tasks. You can use a series of background tasks to schedule and handle 在后台唤醒您的应用程序扩展来:
获取新数据
- 使用WKWatchConnectivityRefreshBackgroundTask从phone获取数据,或者
- 使用WKURLSessionRefreshBackgroundTask从服务器下载数据
- 数据到达后更新您的模型,
- 从模型更新您的并发症(通过重新加载或延长时间线),最后
- 更新应用程序的停靠栏快照以显示停靠栏上的数据
任务完成后立即调用每个任务的setTaskCompleted
方法。
使用应用任务的其他好处
此设计的一个主要特点是手表扩展现在可以处理各种前景和背景场景,包括:
- 在 app/complication 启动时初始加载数据,
- 在后台更新数据,当扩展被后台任务唤醒时,
- 当用户从停靠栏恢复您的应用程序时,在前台更新数据。
Apple 建议您利用获得的每一个机会,无论您的应用程序是在前台还是后台,以使您的复杂功能、应用程序和停靠栏快照保持最新。
有什么限制吗?
每天可用任务总数除以扩展坞中的应用程序数量。 Dock 中的应用程序越少,您的应用程序可以使用的任务就越多。 Dock 中的应用程序越多,您可以使用的应用程序就越少。
如果您的并发症处于活动状态,您的应用每小时至少可以被唤醒四次。
如果您的并发症未激活,您的应用保证至少每小时被唤醒一次。
由于您的应用现在 运行 在后台运行,因此您需要高效快速地完成后台任务。
后台任务受限于 CPU 时间和允许的 CPU 使用量。如果您超过 CPU 时间(或在后台使用超过 CPU 的 10%),系统将终止您的应用程序(导致崩溃)。
了解更多信息
- 中介绍了更新手表应用程序的时间和原因的很好的介绍
具体而言,Keeping Your Watch App Up to Datesession涵盖了让您的复杂功能、应用程序和 Dock 快照保持最新所需的一切。
WatchBackgroundRefresh示例代码演示了如何使用
WKRefreshBackgroundTask
在后台更新WatchKit应用程序。