ios - 为什么即使包含应用程序在前台,iOS 小部件也不会及时刷新

标签 ios swift widget widgetcenter

我对iOS widget的刷新机制做了一些研究:

1 前台包含app,widget刷新不受限制

阅读apple developer docs ,我了解到小部件刷新是由 WidgetKit 预算控制的。正如它所说:

For a widget the user frequently views, a daily budget typically includes from 40 to 70 refreshes

但在以下情况下,重新加载不计入小部件的预算:

  • 小部件的包含应用程序在前台。
  • 小部件的包含应用程序具有事件的音频或导航 session 。
  • 系统区域设置更改。
  • 动态类型或辅助功能设置更改。

2 我们可以使用 WidgetCenter.shared.reloadTimelines 刷新包含应用程序的小部件

同一文档说:

In the game widget example above, if the app receives a push notification indicating a teammate has given the character a healing potion, the app can tell WidgetKit to reload the timeline and update the widget’s content.

3 我在这方面看到了一些很好的实现

类似LiveIn 的应用当我收到 friend 的帖子时,小部件及时刷新让我获得流畅的用户体验(只要包含的应用程序在前台,我猜他们可以使用 Background Refresh 改进这一点)。

该产品不受每日 40 到 70 次刷新预算的限制,我在包含应用程序的图片显示和小部件之间有一点延迟(小到可以忽略)。

4 但我还是卡在这里

但是,当我尝试使用上述 API WidgetCenter.shared.reloadTimelinesWidgetCenter.shared.reloadAllTimelines 构建应用程序时,通知小部件刷新存储在UserDefaults ,我的小部件没有及时响应 API 调用。有时,它可能会卡住超过 10 分钟,这与我上面提到的产品相去甚远。

5 一些黑客尝试

我浏览了很多 Stackoverflow QA 和博客,确实在 iOS 小部件中发现了一些棘手的事情。例如,View._clockHandRotationEffect(.secondHand, in: .current, anchor: .center) API 可用于无限制地刷新小部件 View (通常用于构建基于时钟的应用程序)。

但是好像和containing app和widget之间的消息通知没有关系(或者只是我还没弄明白)。

6 我的问题

所以我的问题来了。 iOS商店中的一些应用已经具备了及时通知小部件的功能,为什么我仍然无法获得官方文档指导下的流畅使用体验?我是否在这里错过了一些重要的事情,或者他们只是在使用我看不到的其他私有(private) API?

代码并不复杂,Xcode 签名很烦人,所以我没有准备一个最小的项目来重现它。你可以拍pawello2222/WidgetExamples作为演示,如果你想试一试。任何提示或线索将不胜感激!

最佳答案

最后,我们获得了流畅的用户体验。乍一看,该解决方案很奇怪,但与我们之前的实现相比,它的效果非常好。

您需要做的就是在应用程序进入前台后尽快调用WidgetCenter.shared.reloadTimelinesWidgetCenter.shared.reloadAllTimelines

为什么?作为文档 Managing Your App's Life Cycle状态:

a foreground app has the user’s attention, so it has priority over system resources, including the CPU

文档写的很清楚,但时间也很重要,有些现象我们测试是原样的,但在任何官方文档中都找不到(在release中运行应用程序,而不是连接xcode的 Debug模式):

  • 始终在前台启动应用程序,通过不断调用 WidgetCenter.shared.reloadTimelinesWidgetCenter.shared.reloadAllTimelines 通知小部件刷新 View ,随着时间的推移延迟会显着增加
  • 在应用启动后调用 WidgetCenter.shared.reloadTimelinesWidgetCenter.shared.reloadAllTimelines 时,widget View 会立即刷新(几乎 100% 成功率)

我见过许多开发人员陷入 iOS 小部件的刷新之谜,最终放弃使用它。希望我的经历能帮助其他人更好地理解并更快地做出决定。

关于ios - 为什么即使包含应用程序在前台,iOS 小部件也不会及时刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72819286/

相关文章:

ios - iOS TrueDepth框架指向点云

ios - 限制在 PDF 页面边界内移动/拖动 pdf 注释

ios - swift 3 : DispatchQueue Timing over URLSession

ios - 在 for 循环中安排本地通知

android - 错误状态 : Too many elements FLUTTER

ios - 为什么我不能调用另一个类的方法?

ios - 如何在单击时为单元格添加边框

ios - 从不同的 View 模型调用服务时绑定(bind)事件未触发

javascript - 将 select2 应用于 ckeditor 中的对话框元素

django 在渲染表单时转义小部件