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

相关推荐
sakiko_10 小时前
OC基础语法(与Swift对比)-1
开发语言·ios·objective-c·swift
未来猫咪花10 小时前
Everything is ViewModel:让状态管理回到对象世界
android·flutter·ios
Crazy_MT11 小时前
不越狱,iPhone 为什么也能安装任意 IPA?聊聊 iLoader、SideStore 和 LiveContainer 的原理
ios·开源
skr爱码士16 小时前
15_国际化和本地化:tr()、ts 文件、QM 文件、多语言切换
c++·qt·ui·客户端
JoyCong199817 小时前
从iPhone Ultra到ToDesk:折叠大屏时代的效率革命,硬件只是开始
大数据·运维·ios·智能手机·iphone·远程工作·远程操作
2501_9160074717 小时前
Flutter与游戏App加固避坑指南:如何为混合开发与高交互应用选对安全方案?
安全·flutter·游戏·ios·小程序·uni-app·iphone
2501_9160088919 小时前
Flutter 开发 iOS,项目打包成 IPA,命令与免 Xcode两种方法
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
SameX2 天前
iOS 独立开发者转鸿蒙:我把足迹地图 App 迁移到 ArkTS 的全过程
ios
东坡肘子2 天前
举手之劳 -- 肘子的 Swift 周报 #151
人工智能·swiftui·swift