タイムラインプロバイダーとスナップショット
時間の経過に応じてウィジェットのコンテンツを提供します。
「タイムラインプロバイダーとスナップショット」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。
プロバイダーの役割
Widgetが継続的に自分自身を更新することはありません。その代わり、TimelineProviderが事前に描画されたエントリのスケジュールをWidgetKitに渡し、システムがそれぞれを適切な時刻に表示します。プロバイダーは、プレースホルダー、スナップショット、タイムラインという3つの問いに答えます。
import WidgetKit
// TimelineProvider supplies:
// placeholder(in:) -> instant skeleton
// getSnapshot(in:) -> one entry for previews
// getTimeline(in:) -> future entries + refresh policyTimelineProviderへの準拠
プロバイダーはTimelineProviderに準拠し、関連するEntry型を指定します。3つのメソッドを実装すると、それぞれにファミリーとプレビューかどうかを示すContextが渡されます。
import WidgetKit
struct WeatherProvider: TimelineProvider {
typealias Entry = WeatherEntry
func placeholder(in context: Context) -> WeatherEntry {
WeatherEntry(date: Date(),
temperature: 20, condition: "Sunny")
}
// getSnapshot and getTimeline follow
}プレースホルダー
placeholder(in:)は、代表的なダミーデータを即座に返す必要があります。システムは、実際のWidgetの読み込み中やWidgetギャラリーで、これをレダクションされたスケルトンとして表示します。ここではネットワークやディスクへのアクセスを決して行わないでください。
import WidgetKit
func placeholder(in context: Context) -> WeatherEntry {
// Synchronous, fake data, no I/O
WeatherEntry(date: Date(),
temperature: 0, condition: "--")
}スナップショット
getSnapshotは、Widgetギャラリーのプレビューなど、一時的な状況に対して単一のエントリを提供します。すぐに返す必要があります。context.isPreviewがtrueの場合は、ギャラリーを瞬時に表示できるよう、時間のかかる取得処理ではなくサンプルデータを使用してください。
import WidgetKit
func getSnapshot(
in context: Context,
completion: @escaping (WeatherEntry) -> Void) {
if context.isPreview {
completion(WeatherEntry(date: Date(),
temperature: 22, condition: "Clear"))
} else {
completion(currentEntry())
}
}タイムライン
getTimelineが中心となる処理です。将来のエントリの配列を作成し、更新ポリシーとともにTimelineにまとめます。システムは各エントリをその日時に描画し、ポリシーに従って新しいタイムラインを要求します。
import WidgetKit
func getTimeline(
in context: Context,
completion: @escaping (Timeline<WeatherEntry>) -> Void) {
let entries = buildEntries()
let timeline = Timeline(
entries: entries, policy: .atEnd)
completion(timeline)
}更新ポリシー
再読み込みポリシーは、WidgetKitが次のタイムラインを要求する時期を制御します。.atEndは最後のエントリの日時の後、.after(date)は指定した時刻、.neverは手動で再読み込みするまで更新しません。システムには更新回数の予算があるため、1秒ごとの更新は期待しないでください。
import WidgetKit
// .atEnd -> reload after final entry
// .after(someDate) -> reload at a chosen time
// .never -> only on manual reloadTimelines
let policy = TimelineReloadPolicy.atEnd
_ = policy将来のエントリの作成
よくある方法は、次の数時間分を事前に計算しておくことです。これにより、更新のたびにコードを起動しなくてもWidgetを更新できます。現在から将来に向けて一定間隔でエントリを生成し、それぞれにその時点のデータを保持させます。
import WidgetKit
import Foundation
func hourlyEntries() -> [WeatherEntry] {
var entries: [WeatherEntry] = []
let now = Date()
for hour in 0..<6 {
let date = Calendar.current.date(
byAdding: .hour, value: hour, to: now)!
entries.append(WeatherEntry(date: date,
temperature: 18 + hour, condition: "Sunny"))
}
return entries
}タイムラインでの非同期データ
ネットワークから取得する必要がある場合は、completionを呼び出す前に実行してください。非同期処理をTaskでラップし、データが到着してから完了させます。プロバイダーに許される時間は短いため、高速に処理してください。
import WidgetKit
func getTimeline(
in context: Context,
completion: @escaping (Timeline<WeatherEntry>) -> Void) {
Task {
let entry = await fetchForecast()
let timeline = Timeline(
entries: [entry], policy: .after(
Date().addingTimeInterval(3600)))
completion(timeline)
}
}
func fetchForecast() async -> WeatherEntry {
WeatherEntry(date: Date(),
temperature: 21, condition: "Cloudy")
}重要度と予算
WidgetKitはバッテリーを保護するため、1日に更新できる回数を制限します。頻繁な更新を強制することはできません。1つのタイムラインに複数のエントリを用意し、妥当な再読み込み時刻を選択してください。アプリからreloadTimelinesを使用するのは、重要なデータ変更があった場合だけにします。
import WidgetKit
// The system, not you, decides exact refresh timing.
// Strategy: pre-bake multiple entries + a sensible policy
// + app-driven reloads on real changes.
let budget = "refreshes are budgeted by the OS"
_ = budget設定可能なWidgetのプロバイダー
AppIntentConfigurationのWidgetでは、代わりにAppIntentTimelineProviderを使用します。このプロバイダーのメソッドにはユーザーが設定したintentが渡されるため、選択された項目(都市やアカウントなど)に応じたデータを取得できます。
import WidgetKit
// AppIntentTimelineProvider adds the configuration:
// func timeline(for configuration: MyIntent,
// in context: Context)
// async -> Timeline<Entry>
let configurable = "intent-aware provider"
_ = configurableプロバイダーを組み立てる
完全なプロバイダーは、即座に返すプレースホルダー、プレビューを考慮した高速なスナップショット、適切な再読み込みポリシーを持つ事前作成済みエントリのタイムラインを提供します。これにより、システムの予算内でWidgetを最新の状態に保てます。
import WidgetKit
// 1. placeholder -> instant dummy
// 2. getSnapshot -> sample when isPreview, else current
// 3. getTimeline -> [entries] + .atEnd or .after
let summary = "three methods, one current widget"
_ = summary確認問題
プレースホルダーメソッドに関する制約を思い出してください。
まとめ
タイムラインプロバイダーについて学びました。
placeholderは即座にダミーデータを返し、getSnapshotは1つのエントリを返します(isPreviewの場合はサンプルを使用します)。getTimelineは将来のエントリとポリシーを返します。- 再読み込みポリシーは
.atEnd、.after(date)、.neverで、実際の更新回数はOSによって制限されます。 - 複数のエントリを事前に作成し、非同期の取得処理は完了を通知する前に行います。
- 設定可能なWidgetでは
AppIntentTimelineProviderを使用します。
AI チューターと学ぶ Swift — 無料
ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。
- コース
- 122
- レッスン
- 409
よくある質問
「タイムラインプロバイダーとスナップショット」レッスンは無料ですか?
はい。「タイムラインプロバイダーとスナップショット」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。
「タイムラインプロバイダーとスナップショット」で何を学びますか?
時間の経過に応じてウィジェットのコンテンツを提供します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Swift Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「タイムラインプロバイダーとスナップショット」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSwift Academyレッスンでコードを書いて実行できますか?
はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- WidgetKitウィジェットの構築
- タイムラインプロバイダーとスナップショット
- App Extensionsの概要
- App IntentsとShortcuts