iOS 小组件开发第二篇:时间线

这里每天分享一个 iOS 的新知识,快来关注我吧

昨天讲了小组件基础,今天来讲讲时间线。

时间线

时间线是小组件刷新数据的机制,简单来说就是让你告诉系统,你需要小组件什么时间展示什么内容。

刷新时间和内容 被封装在 TimelineEntry 对象中:

csharp 复制代码
struct SimpleEntry: TimelineEntry {
    let date: Date
    // 自定义的其他数据...
}

我们可以把它称为时间线条目,方便后文描述,每个条目都可以指定更新小组件内容的日期和时间。

举个例子,比如,9 点刷新一次,9 点半刷新一次,10:05 刷新一次,大概是下面这个图:

展示小组件

首先从用户的角度出发,用户可能会从桌面进入小组件库,然后选择你的 App 下的小组件。

用户在第一次看到你的小组件时,系统会调用 func placeholder(in context: Context) -> SimpleEntry 方法,要求同步返回一个时间线条目来展示小组件的占位,让用户对小组件显示的内容有一个总体了解,通常你可以用一些保底数据来展示。

随后会调用 func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> Void),WidgetKit 会要求程序提供预览快照,需要异步返回一个时间线条目展示小组件。

当然这个方法不仅在小组件库中展示时会调用,其他情况下也可能调用,可以用 context.isPreview 来判断当前是否在组件库中显示,如果是在组件库中展示,completion 需要及时返回,苹果没有说具体多久,但如果你的数据从网络获取,而且时间超过几秒时,你最好先用保底数据返回。

在请求初始快照后,WidgetKit 调用 getTimeline(in:completion:) 以向提供程序请求定期时间线。

这个方法的 completion 的参数为 Timeline<Entry>,Timeline 对象中可以包含多个时间线条目,前面已经说过了,每个时间线条目都包含时间和数据,用来更新小组件,我们以示例程序来讲:

less 复制代码
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
    var entries: [SimpleEntry] = []

    let currentDate = Date()
    for hourOffset in 0 ..< 5 {
        let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
        let entry = SimpleEntry(date: entryDate)
        entries.append(entry)
    }

    let timeline = Timeline(entries: entries, policy: .atEnd)
    completion(timeline)
}
  1. 定义了一个空数组 entries 来存储 Timeline 的条目(Entry)。

  2. 获取当前时间 currentDate。

  3. 通过一个 for 循环, 从当前时间开始, 每次加 1 小时, 总共循环 5 次。这就得到了从现在起 5 个小时内的 5 个时间点。

  4. 对每个时间点, 创建一个 SimpleEntry 对象, 存储这个时间点, 并添加到 entries 数组中。

  5. 使用 entries 数组创建一个 Timeline, 策略设置为 .atEnd

  6. 通过一个 completion handler 将这个 Timeline 返回给调用者。

所以在示例程序中,每个小时会更新一下小组件的内容,5 个小时后,重新请求新的时间线。

再说说 Timeline 的策略(policy)参数,它决定了小组件什么时候刷新,是个枚举,总共有三个值,对应三种刷新策略:

  • atEnd:在时间线中的最后一个日期过后请求新时间线,默认情况下就是这个策略

  • after(Date):可以指定一个未来的日期时间,在这个时间之后重新请求新时间线

  • never:永远不会向小组件请求新的时间线

小组件的刷新频率

前面介绍了时间线的更新策略,但 iOS 系统真的会按照我们设定的时间线来更新吗?答案是不一定!

因为假设你设置时间线每秒钟刷新一次数据,会加重系统的负担,所以苹果对于小组件的刷新频率增加了一些限制,以 24 小时为一个周期,每天能刷新多少次取决于三个条件:

  1. 小组件向用户进行显示的频率和次数。

  2. 小组件的上次重新载入时间。

  3. 小组件的包含 App 是否处于活跃状态。

对于用户经常查看的小组件,每日最大的刷新次数为 40 到 70 次,大致换算为每 15 到 60 分钟重载一次小组件。

下一篇我们将实战做一个小组件,相信做完之后你会更理解时间线的概念。

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
黑科技iOS上架19 小时前
双引擎解决oc/swift开发引用加固难题
开发语言·ios·swift·审核·ios混淆·执行程序差异化
wechatbot88820 小时前
企微第三方自动化开发:原生能力无阉割 API 开放平台介绍
后端·ios·微信·企业微信·ai编程·ipad
黑科技iOS上架21 小时前
iOS framework/dylib动态库定向加固实战
macos·ios·objective-c·cocoa·审核·ios混淆·执行程序差异化
可乐鸡翅yeah_2 天前
fmp4 碎片 MP4 格式 HLS 流,和传统 TS 分片有什么不一样
开发语言·javascript·ios·音视频·safari·m3u8·m3u8在线播放
茶底世界之下2 天前
为什么高精度透明图片上传到 Metal 时,必须把“拷贝像素”与“混合合成”分开
ios
老李IT笔记2 天前
iOS 27 更新延迟只能给 1 到 90 天:两个参数怎么配,配错了会发生什么
ios·智能手机
Helix2502 天前
移动端浏览器内核之争:iOS 为何强制使用 WebKit?
ios·safari·webkit·wkwebview·浏览器内核·blink·ios浏览器内核
传奇开心果编程2 天前
【SwiftUI提高练中学】第13课 实时活动与灵动岛:ActivityKit 实战
学习·ui·ios·swiftui·swift