何时何地获取Watch Complication的数据

时间:2015-09-27 23:34:22

标签: ios watchkit apple-watch-complication watch-os-2 clockkit

在对并发症进行了几天的处理之后,我有信心对于以规定间隔发生的更新的更新过程进行以下说明:

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

Apple的文档很清楚,您不应该经常询问更新,或者在复杂化代码中进行太多处理,否则您将耗尽时间预算,并且您的并发症将停止更新。所以,我的问题是:你在何时何地进行更新?

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

放置网址获取代码最明显的地方是func requestedUpdateDidBegin()获取数据,存储数据,如果没有更改,只需返回即可。如果有更改,则延长或重新加载时间线。

但是,提取网址的成本可能很高。备选方案:

  • 将代码放在手机应用程序上并使用WCSession发送,但如果用户关闭该应用程序,则不再进行更新。
  • 使用推送更新,但这不是一个网络应用,所以我没有地方发送它们。
  • 显然,当用户与手表应用程序交互时,我会更新所有数据,但现在这意味着只有在用户使用应用程序时才会更新,这样就无需复杂化。

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

2 个答案:

答案 0 :(得分:24)

对于watchOS 3,Apple建议您从使用并发数据源getNextRequestedUpdateDate预定更新切换到更新并发症。

watchOS 2的旧方式

requestedUpdateDidBegin()实际上只是为了更新复杂功能而设计的。保持您的复杂功能(并观看应用程序)是最新的通常涉及的不仅仅是重新加载时间轴(并且异步检索数据永远不适合旧方法)。

watchOS 3的新方式

新的更好的方法是使用background refresh app tasks。您可以使用一系列后台任务来schedulehandle您的应用扩展程序在后台被唤醒:

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

使用app任务的其他好处

此设计的一个关键功能是手表扩展现在可以处理各种前景和背景场景,包括:

  • 最初在您的应用/复杂功能开始时加载数据,
  • 当后台任务唤醒扩展时,后台更新数据,
  • 当用户从扩展坞恢复您的应用时,更新前台中的数据。

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

有任何限制吗?

每天可用任务总数除以停靠栏中的应用数量。 Dock中的应用程序越少,您的应用程序可以使用的任务就越多。 Dock中的应用程序越多,您可以使用的就越少。

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

  • 如果你的并发症没有激活,你的应用程序肯定会每小时至少被唤醒一次。

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

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

了解更多信息

答案 1 :(得分:4)

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

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

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

如果您无法访问APNS,请不要以后台模式运行您的iOS应用,并且不想从Apple Watch发出HTTP请求,我可以想到2其他选择。

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

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

  

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

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

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