正确使用HKObserverQuery的后台更新completionHandler

osp*_*spr 68 background ios healthkit hkobserverquery

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

- initWithSampleType:predicate:updateHandler:
Run Code Online (Sandbox Code Playgroud)

updateHandler有一个completionHandler具有以下文件:

该块传递给更新处理程序.完成处理传入数据后,必须立即调用此块.调用此块告诉HealthKit您已成功接收到后台数据.如果您不调用此块,HealthKit将继续尝试使用退避算法启动您的应用.如果您的应用无法响应三次,HealthKit会假定您的应用无法接收数据,并停止向您发送后台更新.

通过查看其他帖子,似乎围绕此处理程序存在很多混乱.以下是我对它的一些问题:

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

Ale*_*kov 1

什么时候应该调用处理程序?

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

为什么需要这个?

所有此类处理程序都有完成闭包。iOS 需要它们来了解您的应用程序是否正常运行。如果您的应用程序占用太多 CPU 时间,那么 iOS 可能会变得很慢。因此,苹果希望确保 iOS 能够在应用程序质量不佳的情况下正常运行。

如果您点击后台更新三击并且 HK 停止发送更新,这是永久性的吗?

不。

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

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

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

这是未知的。这取决于很多因素。如果 iPhone 正在充电,它可能会允许您的应用程序运行更长时间,只是为了估计完成句柄是否被调用。如果您的 iPhone 未充电且电量接近 0%,那么 iOS 更有可能会终止您的应用程序。因此,在调用完成处理程序后,您不应该执行任何操作。并尽量保持简单。

建议

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

1-2 秒或更短的时间是后台更新的最佳时间。