• 作者:老汪软件技巧
  • 发表时间:2024-10-08 00:01
  • 浏览量:

Timeline

时间线(Timeline)是小组件刷新数据的机制。开发者可以在时间线提供者中动态生成不同时间点的条目,并设置更新策略。

简单来说时间线(Timeline)就是告诉系统,你需要小组件在什么时间展示什么内容。

struct Provider: TimelineProvider {
    ...
    func getTimeline(in context: Context, completion: @escaping (Timeline) -> ()) {
        var entries: [SimpleEntry] = []
        let timeline = Timeline(entries: entries, policy: .atEnd)
        completion(timeline)
    }
}

小组件通过Provider 实现的funcgetTimeline(in:,completion:) 方法提供所需刷新数据对象Timeline,并通过 completion 回调返回。

Timeline时间线属性:

刷新数据所需的 时间和内容 被封装在实现 TimelineEntry 协议的结构体 SimpleEntry 中:

Timeline 是一个以 TimelineEntry 为元素的数组,每个条目都可以指定更新小组件内容的日期和时间。

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

更新策略

struct Provider: TimelineProvider {
    ...
    func getTimeline(in context: Context, completion: @escaping (Timeline) -> ()) {
        ...
        let timeline = Timeline(entries: entries, policy: .atEnd)
        completion(timeline)
    }
}

小组件的更新策略同样配置在Timeline 中,不同的刷新策略决定不同的时间线更新时机。

public struct TimelineReloadPolicy : Equatable {
    /// A policy that specifies that WidgetKit requests a new timeline after
    /// the last date in a timeline passes.
    public static let atEnd: TimelineReloadPolicy
    /// A policy that specifies that the app prompts WidgetKit when a new
    /// timeline is available.
    public static let never: TimelineReloadPolicy
    /// A policy that specifies a future date for WidgetKit to request a new
    /// timeline.
    public static func after(_ date: Date) -> TimelineReloadPolicy
}

更新策略policy 是一个 TimelineReloadPolicy 结构体,包含3种类型:

例如,模版示例代码中设置了一个策略为 .atEnd,意味着当时间线的最后一个条目被用完后,系统将自动请求新的数据。

struct Provider: TimelineProvider {
    ...
    func getTimeline(in context: Context, completion: @escaping (Timeline) -> ()) {
        var entries: [SimpleEntry] = []
        // Generate a timeline consisting of five entries an hour apart, starting from the current date.
        let currentDate = Date()
        for hourOffset in 0 ..< 5 {
            let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
            let entry = SimpleEntry(date: entryDate, emoji: "")
            entries.append(entry)
        }
        let timeline = Timeline(entries: entries, policy: .atEnd)
        completion(timeline)
    }
}

刷新机制

所谓的小组件刷新,其实是刷新了 Timeline,导致由 Timeline 数据驱动的小组件视图发生了改变。小组件的刷新机制可分为两种:

1.System reloads

由系统发起的Timeline 刷新,系统决定每个不同的Timeline 的刷新频次。

System reloads刷新限制:

以 24 小时为一个周期,每天能刷新多少次取决于三个条件:

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

2.App-driven reloads

由 App 触发小组件Timeline 刷新。

App-driven reloads 可以通过WidgetCenter 手动刷新时间线

刷新所有时间线:

WidgetCenter.shared.reloadAllTimelines()

刷新指定小组件:

// xx 为小组件的kind
WidgetCenter.shared.reloadTimelines(ofKind: "xx")

参考

/post/729168…

本文同步自微信公众号 "" ,这里只是同步,想看及时消息请移步我的公众号,不定时更新我的学习经验。