|
| 1 | +--- |
| 2 | +sitemap: |
| 3 | + exclude: false |
| 4 | + changefreq: hourly |
| 5 | +title: 'iOS 小组件开发之核心方法调用时机' |
| 6 | +date: 2024-10-22 |
| 7 | +tags: |
| 8 | +- swift |
| 9 | +- ios |
| 10 | +- widgetkit |
| 11 | +--- |
| 12 | + |
| 13 | +在开发 **iOS 小组件 (Widget)** 时,`placeholder`、`getSnapshot` 和 `getTimeline` 是 **WidgetKit** 的核心方法,它们的调用时机关系到组件的**加载状态**和**数据刷新**流程。下面是详细说明它们的调用时机及作用: |
| 14 | + |
| 15 | +--- |
| 16 | + |
| 17 | +## **1. placeholder 的调用时机** |
| 18 | +`placeholder` 方法用于**占位内容**,即小组件在加载完成前展示的默认视图。 |
| 19 | + |
| 20 | +- **什么时候调用?** |
| 21 | + - 在小组件刚添加到主屏幕时。 |
| 22 | + - 系统或 Widget 需要**快速展示**内容(通常在数据尚未加载时)。 |
| 23 | + - 在 **Widget 预览模式**(如用户在添加小组件时浏览不同尺寸的预览)。 |
| 24 | + |
| 25 | +- **适用场景:** |
| 26 | + - 使用占位符数据来显示小组件的基本布局,不需要实际数据。 |
| 27 | + |
| 28 | +**示例代码:** |
| 29 | +```swift |
| 30 | +func placeholder(in context: Context) -> SimpleEntry { |
| 31 | + SimpleEntry(date: Date(), message: "加载中...") |
| 32 | +} |
| 33 | +``` |
| 34 | + |
| 35 | +--- |
| 36 | + |
| 37 | +## **2. getSnapshot 的调用时机** |
| 38 | +`getSnapshot` 方法用于生成**静态快照**,即当系统需要**快速加载和展示**当前视图时使用。 |
| 39 | +- **什么时候调用?** |
| 40 | + - 当用户**查看小组件的预览**(例如在主屏幕上长按时)。 |
| 41 | + - 当系统**无法立即获取完整数据**,需要快速显示快照。 |
| 42 | + |
| 43 | +- **特点:** |
| 44 | + - 该方法的执行速度需要尽量**快**,通常返回**最近一次的缓存数据**。 |
| 45 | + - 在一些静态内容的小组件中,`getSnapshot` 可能会频繁调用。 |
| 46 | + |
| 47 | +**示例代码:** |
| 48 | +```swift |
| 49 | +func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> Void) { |
| 50 | + let entry = SimpleEntry(date: Date(), message: "快照数据") |
| 51 | + completion(entry) |
| 52 | +} |
| 53 | +``` |
| 54 | + |
| 55 | +--- |
| 56 | + |
| 57 | +## **3. getTimeline 的调用时机** |
| 58 | +`getTimeline` 是**核心数据更新方法**,用于生成一系列的时间条目 (`TimelineEntry`),并决定小组件**何时刷新**。 |
| 59 | + |
| 60 | +- **什么时候调用?** |
| 61 | + - **首次加载**小组件时。 |
| 62 | + - **定时刷新**,由你通过时间表或策略 (`Timeline`) 控制刷新频率。 |
| 63 | + - 在**用户交互或系统事件触发**刷新时。 |
| 64 | + |
| 65 | +- **特点:** |
| 66 | + - 你可以通过设置**刷新策略**(如固定时间间隔、到期后刷新等)来控制更新频率。 |
| 67 | + - 合理控制刷新时间非常重要,频繁更新会影响性能和耗电量。 |
| 68 | + |
| 69 | +**示例代码:** |
| 70 | +```swift |
| 71 | +func getTimeline(in context: Context, completion: @escaping (Timeline<SimpleEntry>) -> Void) { |
| 72 | + let currentDate = Date() |
| 73 | + let nextUpdate = Calendar.current.date(byAdding: .minute, value: 15, to: currentDate)! |
| 74 | + |
| 75 | + let entry = SimpleEntry(date: currentDate, message: "最新数据") |
| 76 | + let timeline = Timeline(entries: [entry], policy: .after(nextUpdate)) |
| 77 | + |
| 78 | + completion(timeline) |
| 79 | +} |
| 80 | +``` |
| 81 | + |
| 82 | +--- |
| 83 | + |
| 84 | +## **调用顺序与流程图** |
| 85 | + |
| 86 | +1. **首次加载小组件:** |
| 87 | + - 调用 `placeholder` 显示占位内容 → 调用 `getSnapshot` 展示快照 → 调用 `getTimeline` 获取完整数据并更新。 |
| 88 | + |
| 89 | +2. **用户查看预览或长按:** |
| 90 | + - 调用 `getSnapshot` 快速加载当前状态。 |
| 91 | + |
| 92 | +3. **定时或事件触发更新:** |
| 93 | + - 调用 `getTimeline` 更新数据并生成新的时间表。 |
| 94 | + |
| 95 | +--- |
| 96 | + |
| 97 | +## **总结** |
| 98 | + |
| 99 | +| **方法** | **调用时机** | **作用** | |
| 100 | +|------------------|----------------------------------------------------|-----------------------------------------| |
| 101 | +| `placeholder` | 小组件加载或预览时 | 展示基本布局的占位符,不含实际数据 | |
| 102 | +| `getSnapshot` | 预览模式或需要快速展示内容时 | 提供当前状态的快照,速度快,使用缓存数据 | |
| 103 | +| `getTimeline` | 数据刷新或系统定时触发时 | 生成时间表并决定何时刷新数据 | |
| 104 | + |
| 105 | +--- |
| 106 | + |
| 107 | +通过合理使用这三个方法,你可以确保小组件**快速加载、平滑更新**,并在**性能与电量**之间取得良好平衡。 |
0 commit comments