如何判断iOS Today Widget是否在后台更新?

How to tell if iOS Today Widget is being updated in the background?

我有一个 iOS Today Widget,它进行昂贵的 API 调用(昂贵的是因为它被调用的越多,我付的钱就越多)。如果我在我的小部件中实现了 widgetPerformUpdateWithCompletionHandler,那么该小部件每天可以在后台更新几次,而无需用户查看他们的通知中心。

在应用程序中,application:didFinishLaunchingWithOptions 的选项字典中有一个键值对告诉您应用程序是否正在启动后台,但在小部件中没有类似的东西我能找到。还有在 UIApplication 中获取 applicationState 的调用,这在 widget 中也是不可用的。

那么,我的小部件中是否有任何可靠方式来了解系统正在后台更新我的小部件并且用户没有查看他们的通知中心来保存我自己免于不必要的 API 电话?当用户确实查看小部件时,我可以接受内容不是完全最新的,因为我可以在加载后很快更新它。

我一直在尝试寻找一个 hacky 解决方案,比如与视图不同的东西,或者 window 在后台更新小部件时不同的东西,但还没有找到任何东西。我注意到偶尔在后台初始化小部件时 window 框架的高度为零,但情况似乎并非总是如此。

我也知道,如果我不实现 widgetPerformUpdateWithCompletionHandler,那么我的小部件就不会在后台更新,这是一个可能的解决方案,但我正在寻找一种方法来获得我的蛋糕和也吃

如果有人有任何其他想法,我会洗耳恭听。谢谢

如果您只是计划调试并了解它被调用的频率,您可以在设备上使用一些日志记录(甚至可能在每次调用 widgetPerformUpdateWithCompletionHandler 时触发某种分析事件通知,以便调解这种情况是否经常发生)。

减少请求数量的主动解决方案的一个例子是对请求进行时间限制,如果 widgetPerformUpdateWithCompletionHandlerx 运行一次以上 minutes/hours/etc 您不会调用 API,而只是调用没有新数据的 completionBlock

最后一个对 API 调用有更严格限制的例子可能是在今天的分机上完全避免它们(就像你说的那样)。这意味着 API 调用只会在实际应用程序启动时完成,并且响应会持续存在(您可以在应用程序和 Today's extension 之间有一个共享容器 - 只是一个文件夹,甚至更复杂的东西,比如 sqlite存储核心数据)并始终从共享容器中检索数据以更新今日扩展 UI。

widgetPerformUpdateWithCompletionHandler 实际上在 iOS 中非常不可靠 9. 如果您只是从 viewDidLoad 在后台启动您的网络调用,它只会在您的今天小部件出现时调用在屏幕上。

我就此提交了 Apple 开发者技术支持请求。他们回应并告诉我,这是不可能的,我需要为此提交增强请求。我提交了rdar://27434852.