33

在处理了几天的并发症后,我有信心对按规定时间间隔发生的更新的更新过程说以下内容:

  • 系统调用requestedUpdateDidBegin()
    • 您可以在此处确定您的数据是否已更改。如果没有,您的应用程序无需执行任何操作。如果您的数据已更改,您需要致电:
      • reloadTimelineForComplication如果您的所有数据都需要重置。
      • extendTimelineForComplication如果您只需要在并发症时间线的末尾添加新项目。
    • 注意:系统实际上可能会调用requestedUpdateBudgetExhausted(),而不是requestedUpdateDidBegin()如果您在当天花费了过多的并发症时间预算。这就是这个问题的原因。
  • 如果您调用reloadTimelineForComplication,系统将调用getCurrentTimelineEntryForComplication(以及获取数组的未来和过去变体,具体取决于您的时间旅行设置)
  • 这是猜想,因为我还没有测试它,但我相信如果你调用extendTimelineForComplication它,只会getTimelineEntriesForComplication(... afterDate date: NSDate ...)调用它。
  • 然后系统将调用getNextRequestedUpdateDateWithHandler,以便您可以指定您的并发症需要多长时间才能进行新的更新。

Apple 的文档非常清楚,您不应该过于频繁地要求更新,或者在并发症代码中进行过多的处理,否则您将耗尽您的时间预算,您的并发症将停止更新。所以,我的问题是:您在何时何地进行更新?

对于上下文,我的场景是一个 URL,其返回数据每小时最多更改两次。

放置 URL 获取代码最明显的地方是func requestedUpdateDidBegin()获取数据,存储它,如果没有变化,就返回。如果有更改,则延长或重新加载时间线。

但是,获取 URL 的成本可能很高。备择方案:

  • 将代码放在手机应用程序上并使用 发送WCSession,但如果用户关闭该应用程序,则更新将不再发生。
  • 使用推送更新,但这不是网络应用程序,所以我没有地方可以发送它们。
  • 显然,当用户与手表应用程序交互时,我会更新所有数据,但这意味着它仅在用户使用应用程序时才会更新,这消除了对复杂性的需求。

还有其他地方吗?我可以在手表应用程序中设置不属于复杂功能的周期性功能吗?获取复杂功能更新数据的正确位置在哪里?

4

2 回答 2

29

对于 watchOS 3,Apple 建议您从使用复杂功能数据源getNextRequestedUpdateDate计划更新来更新您的复杂功能。

watchOS 2 的旧方式

requestedUpdateDidBegin()真的只是为了更新并发症。使您的复杂功能(和手表应用程序)保持最新通常不仅仅需要重新加载时间线(并且异步检索数据永远不适合旧方法)。

watchOS 3 的新方式

新的更好的方法是使用后台刷新应用程序任务。您可以使用一系列后台任务来安排处理您的应用程序扩展在后台被唤醒以:

任务完成后立即调用每个任务的setTaskCompleted方法。

使用应用程序任务的其他好处

此设计的主要特点之一是手表扩展现在可以处理各种前景和背景场景,包括:

  • 最初在您的应用程序/复杂性启动时加载数据,
  • 当扩展被后台任务唤醒时,在后台更新数据,以及
  • 当用户从 Dock 中恢复您的应用程序时,在前台更新数据。

Apple 建议您利用所获得的每个机会,无论您的应用程序是在前台还是在后台,以使您的复杂功能、应用程序和停靠快照保持最新。

有什么限制吗?

每天可用任务的总数在 Dock 中的应用程序数量中分配。Dock 中的应用程序越少,您的应用程序可以使用的任务就越多。扩展坞中的应用程序越多,您可以使用的应用程序就越少。

  • 如果您的并发症处于活动状态,您的应用每小时至少可以唤醒四次。

  • 如果您的并发症未激活,则保证您的应用每小时至少被唤醒一次。

由于您的应用程序现在在后台运行,因此您需要高效、快速地完成后台任务。

后台任务受 CPU 时间量和允许它们使用的 CPU 使用量的限制。如果您超过 CPU 时间(或在后台使用超过 10% 的 CPU),系统将终止您的应用程序(导致崩溃)。

了解更多信息

于 2016-06-16T18:44:21.710 回答
3

编辑:El Tea (op) 在https://stackoverflow.com/a/32994055/630614发布了一个很好的答案

这是一个有趣的问题/问题,我一直在想很多相同的问题!

在大多数情况下,似乎当我在处理一个新的复杂功能时,我需要退后一步,看看我什么时候真的更新它。当设置了“结束日期”时,“倒计时”复杂功能可以一次设置所有未来的时间线条目。NSUserDefaults当 APNS 通过时,显示 Web 服务当前状态的应用程序可能会存储相关数据。

如果您无权访问 APNS,不想在后台模式下运行您的 iOS 应用程序,并且不想从 Apple Watch 发出 HTTP 请求,我可以考虑其他 2 个选项。

1)安排本地通知。好的部分是您的 Apple Watch 应该可以运行didReceiveLocalNotification,但不好的部分是当您只是尝试在不中断的情况下检查状态时,用户会收到通知。

2)通过您的方法向iOS发送消息,设置为使其尽可能快:sendMessage(_:replyHandler:errorHandler:)reloadTimelineForComplicationnilreplyHandler

在 WatchKit 扩展程序处于活动状态并运行时调用此方法会在后台唤醒相应的 iOS 应用程序并使其可访问。

您的 iOS 应用程序可以执行任何需要的网络请求,然后存储信息或将其推送到 Apple Watch。不幸的是,我认为在session.didReceive...您运行手表扩展程序之前不会调用它,但您可以在下次调用requestedUpdateDidBegin.

正如我所说,我对同样的事情非常感兴趣,所以发表一些想法,也许我们可以在这里推断出一些最佳实践。

于 2015-09-28T16:40:48.323 回答