这里每天分享一个 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)
}
-
定义了一个空数组 entries 来存储
Timeline
的条目(Entry
)。 -
获取当前时间
currentDate
。 -
通过一个 for 循环, 从当前时间开始, 每次加 1 小时, 总共循环 5 次。这就得到了从现在起 5 个小时内的 5 个时间点。
-
对每个时间点, 创建一个
SimpleEntry
对象, 存储这个时间点, 并添加到entries
数组中。 -
使用
entries
数组创建一个Timeline
, 策略设置为.atEnd
-
通过一个
completion handler
将这个Timeline
返回给调用者。
所以在示例程序中,每个小时会更新一下小组件的内容,5 个小时后,重新请求新的时间线。
再说说 Timeline
的策略(policy
)参数,它决定了小组件什么时候刷新,是个枚举,总共有三个值,对应三种刷新策略:
-
atEnd
:在时间线中的最后一个日期过后请求新时间线,默认情况下就是这个策略 -
after(Date)
:可以指定一个未来的日期时间,在这个时间之后重新请求新时间线 -
never
:永远不会向小组件请求新的时间线
小组件的刷新频率
前面介绍了时间线的更新策略,但 iOS 系统真的会按照我们设定的时间线来更新吗?答案是不一定!
因为假设你设置时间线每秒钟刷新一次数据,会加重系统的负担,所以苹果对于小组件的刷新频率增加了一些限制,以 24 小时为一个周期,每天能刷新多少次取决于三个条件:
-
小组件向用户进行显示的频率和次数。
-
小组件的上次重新载入时间。
-
小组件的包含 App 是否处于活跃状态。
对于用户经常查看的小组件,每日最大的刷新次数为 40 到 70 次,大致换算为每 15 到 60 分钟重载一次小组件。
下一篇我们将实战做一个小组件,相信做完之后你会更理解时间线的概念。
这里每天分享一个 iOS 的新知识,快来关注我吧
本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!