iOS : HKObserverQuery 的后台更新completionHandler 的使用

Posted

技术标签:

【中文标题】iOS : HKObserverQuery 的后台更新completionHandler 的使用【英文标题】:iOS : Use of HKObserverQuery's background update completionHandler 【发布时间】:2015-05-09 17:57:30 【问题描述】:

HKObserverQuery有如下方法支持后台接收更新:

- initWithSampleType:predicate:updateHandler:

updateHandler 有一个completionHandler,它有以下documentation:

这个块被传递给更新处理程序。你必须调用这个块 处理完传入数据后。调用这个 块告诉 HealthKit 你已经成功收到 后台数据。如果你不调用这个块,HealthKit 会继续 尝试使用退避算法启动您的应用程序。如果你的应用 未能响应 3 次,HealthKit 假定您的应用程序无法响应 接收数据,并停止向您发送后台更新。

从查看其他帖子看来,围绕这个处理程序似乎有很多困惑。以下是我对此的一些疑问:

应该何时调用处理程序?如果调用得太晚,那么 HK 可能会认为应用程序从未收到查询更新,从而导致您点击后台更新 3-strikes back-off 算法。文档声明它应该在处理其他查询后调用。根据运行这些查询需要多长时间,听起来您可能会很危险地接近触发后台更新警报。 为什么需要这个?系统不应该知道应用程序已经启动并收到了后台更新吗?在后台使用CoreBluetooth 时,它只会在后台唤醒您的应用程序 10 秒。无需调用任何处理程序或处理后台更新 3-strikes。 如果你点击后台更新 3-strikes 并且 HK 停止发送更新是永久的吗? HK是否会再次开始发送后台更新?如果有一个错误阻止了处理程序被调用并且现在你已经修复了它怎么办。应用程序是否卡住了,永远不会收到更新?还是会在应用重新启动或更新时重置? HK 是否让您的应用程序在后台运行,直到调用处理程序?这是其目的的一部分还是只是副作用?如果这是其目的的一部分,我们可以在需要停止之前运行多长时间(并触发第一次后台更新罢工)?

【问题讨论】:

这些是目前文档中没有回答的重要问题。 【参考方案1】:

应该何时调用处理程序?

完成工作后调用它。您的代码不应执行复杂的操作。该应用程序在后台,用户看不到发生了什么变化。您可以在用户启动应用程序后设置一个数据更新的“标志”并执行复杂的操作。如果您决定是否通知用户是基于复杂的操作,那么请尝试重构代码,以便预先计算所有必要的数据(例如在 UserDefaults 中),并使用该数据简单地获取额外的数据。所以,1-2 秒就够你计算了。

为什么需要这个?

所有此类处理程序都有完成闭包。 ios 需要它们来了解您的应用程序是否正常工作。如果您的应用程序会占用过多的 CPU 时间,那么 iOS 可能会变慢。因此,Apple 希望确保 iOS 在应用不良的情况下也能正常运行。

如果您点击后台更新 3 次,HK 停止发送更新,这是永久的吗?

没有。

HK 是否会再次开始发送后台更新?

是的。但这取决于许多因素。它可能会在 1-2 天内再次尝试调用您的应用。如果没有任何变化,它将很少调用它。

在调用处理程序之前,HK 是否让您的应用在后台运行?

这是未知的。这取决于许多因素。可能如果 iPhone 正在充电,它将允许您的应用程序运行更长时间,以估计是否调用了完成句柄。如果你的 iPhone 没有充电并且电池电量接近 0%,那么 iOS 更有可能杀死你的应用程序。因此,在调用完成处理程序后,您不应该做任何工作。并尽量保持简单。

建议

您应该尽快处理新数据。如果您需要获取大量数据,则尝试对其进行优化并在应用程序处于前台时对其进行预计算,然后保存在某处(UserDefault),并使用带有缓存数据的新数据来做出决定(例如,通知用户有关一些东西;我相信您需要为此进行背景更新)。

1-2 秒或更短的时间是后台更新的好时机。

【讨论】:

以上是关于iOS : HKObserverQuery 的后台更新completionHandler 的使用的主要内容,如果未能解决你的问题,请参考以下文章

HKObserverQuery 仅在应用程序重新打开时运行

添加新数据并设置 hkObserverQuery 时,HealthKit 不启动应用程序

HKObserverQuery 无法在 iPhone 上运行

从 HKObserverQuery 获取结果

HKObserverQuery 连续两次随机调用

HKObserverQueryCompletionHandler 超时?