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新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
tink20 分钟前
告别 Xcode IDE:用 VS Code + SweetPad + XcodeGen 开发 iOS 应用的完整指南
ios·swiftui·xcode
辉夜技术1 小时前
iPad 插着数据线,Mac 却说"附近没有任何显示器"
客户端
传奇开心果编程1 小时前
【Compose Multiplatform 跨端开发学与练】第8课 资源管理与主题
android·windows·学习·ios·kotlin·web·composer
传奇开心果编程3 小时前
【Compose Multiplatform 跨端开发学与练】第9课 测试与调试
android·学习·macos·ios·kotlin·web·composer
传奇开心果编程3 小时前
【Compose Multiplatform 跨端开发学与练】第4课 导航与路由
android·windows·学习·ui·ios·kotlin·composer
黑科技iOS上架3 小时前
iOS隐私合规扫描工具
ios·审核
传奇开心果编程3 小时前
【Compose Multiplatform 跨端开发学与练】第6课 状态管理与架构
android·学习·ui·ios·架构·kotlin·composer
传奇开心果编程4 小时前
【Compose Multiplatform 跨端开发学与练】第2课 Compose 基础语法
android·windows·学习·ui·ios·kotlin·composer
可乐鸡翅yeah_4 小时前
hls.js 缓冲区参数 maxBufferLength、maxBufferSize 通俗讲解与业务调参
开发语言·javascript·ios·音视频·safari·m3u8