WidgetKit — とは、ウィジェットフレームワークとSwiftUI

著者: IT Sectr 公開日: 2026-06-16 読了時間: 9 分

WidgetKitはiOS 14で導入されたAppleのフレームワークで、開発者がiPhoneやiPadのホーム画面、Macのデスクトップ、Apple Watchの文字盤に動的ウィジェットを配置できるようにします。ウィジェットはアプリを開かずに主要な情報を表示します — 天気予報、為替レート、カレンダー、歩数。Apple Developer Documentation, 2026によると、WidgetKitはAppleエコシステム内で毎日最大20億のウィジェット更新を処理しており、システム画面に情報を表示するための最も使用されているフレームワークの1つとなっています。

重要なポイント

  • WidgetKitはiOS 14+、iPadOS 14+、macOS 11+、watchOS 10+でSwiftUIによるレンダリングでウィジェットを作成するためのフレームワークです。
  • TimelineProviderは、TimelineEntryに基づいてウィジェットがいつ、どのくらいの頻度でコンテンツを更新するかを決定するプロトコルです。
  • WidgetFamily — 3つのサイズ(small、medium、large)があり、開発者はそれぞれを個別に設定できます。
  • WidgetConfigurationはウィジェットのエントリポイントであり、設定タイプ(Static、Intent、AppEntity)とサイズファミリを定義します。
  • 制限事項 — ウィジェットはアニメーション化されておらず、ビデオ、キーボード、内部スクロールをサポートしていません。

WidgetKitとは何か、どのように動作するか?

WidgetKitは、Appleデバイスのシステム画面にコンテンツを表示するウィジェットを作成するためのAppleのフレームワークです。ウィジェットはアプリのミニチュア表現であり、ユーザーがジグルモードでホーム画面に配置します。WidgetKit以前に存在していたwatchOSのコンプリケーションとは異なり、新しいフレームワークは単一のSwiftUI APIを通じてすべてのAppleプラットフォームのウィジェット作成を統一しました。

WidgetKitの動作原理はTimelineProviderに基づいています — これは、順序付けられたTimelineEntryの配列を作成するオブジェクトで、各エントリにはSnapshot(特定の時点でのウィジェットの特定の状態)が含まれています。システムはエントリを順次表示し、タイムライン上の次のエントリに移動するときにウィジェットを更新します。エントリ間では、WidgetKitはアプリコードを呼び出しません — CPU時間は新しいTimelineを作成するときにのみ消費されます。

WWDC 2024セッション「WidgetKit:What’s new」によると、平均的なiOSユーザーのホーム画面には8~12個のウィジェットがあり、最も人気のあるカテゴリは天気、時間、カレンダー、フィットネス、ファイナンスです。WidgetKitは、リアルタイム更新ではなくスケジュールされた更新のおかげで、通常の使用で1日あたり1%未満のバッテリー消費です。

WidgetKitが古いToday Extensionsと異なる点

iOS 14以前は、ウィジェットはToday Viewとしてのみ存在していました — 最初の画面から左にスワイプしてアクセスできるパネルです。Today Extensionsには深刻な制限がありました:「Today」画面でのみ利用可能で、コンテンツを更新するためにアプリを開く必要があり、サイズサポートも限られていました。WidgetKitはToday Extensionsを完全に置き換え、ホーム画面、ロック画面(iOS 16+)、Macデスクトップにウィジェットを提供しました。

  • Today Viewだけでなく、ホーム画面のウィジェット
  • TimelineProviderによる自律的な更新、アプリを開かずに
  • 1つではなく3つの事前定義サイズ
  • Smart RotateとSmart Stack — システムによる自動ウィジェットローテーション
  • すべてのAppleプラットフォーム向けの統一SwiftUI API

WidgetKitのアーキテクチャ:TimelineProviderとEntry

WidgetKitのアーキテクチャは、3つの主要なプロトコルに基づいています:TimelineProviderTimelineEntryWidget。TimelineEntryは、特定の時点でのウィジェットの状態を表すデータモデルです。TimelineProviderはそのようなエントリの配列(Timeline)を作成し、それぞれのアクティベーション日を指定します。WidgetはプロバイダーをSwiftUIビューに接続するエントリポイントです。

TimelineメソッドgetTimelineは、ウィジェットが最初に追加されたときにシステムによって呼び出され、その後定期的に — 通常はプロバイダーのタイプに応じて1~6時間ごとに — 呼び出されます。Timelineには数時間または数日先のエントリを含めることができ、ウィジェットは更新間でアプリコードを呼び出さずに動作できます。緊急のウィジェット更新が必要な場合(例えば、為替レートが変わった場合)、アプリはWidgetCenter.shared.reloadAllTimelines()を強制的に呼び出すことができます。

基本のTimelineProvider

swift
struct SimpleEntry: TimelineEntry {
    let date: Date
    let value: Double
}

struct Provider: TimelineProvider {
    typealias Entry = SimpleEntry
    
    func placeholder(in context: Context) -> Entry {
        Entry(date: Date(), value: 0)
    }
    
    func getSnapshot(
        in context: Context,
        completion: @escaping (Entry) -> Void
    ) {
        Entry(date: Date(), value: 42.5)
    }
    
    func getTimeline(
        in context: Context,
        completion: @escaping (Timeline<Entry>, Error?) -> Void
    ) {
        let entry = Entry(date: Date(), value: fetchLatestValue())
        let nextUpdate = Calendar.current
            .date(byAdding: .hour, value: 1, to: Date())!
        let timeline = Timeline(entries: [entry], policy: .after(nextUpdate))
        completion(timeline, nil)
    }
}

Widget Family:small、medium、large

WidgetKitは3つのウィジェットサイズをサポートしており、それぞれ固定の比率です。Small(iPhoneで170×170 pt)はコンパクトな情報を表示します — 単一の値、アイコン、または短いテキスト。Medium(364×170 pt)はsmallの2倍の幅で、値のペアやミニチャートの表示に適しています。Large(364×382 pt)は縦に画面のほぼ半分を占有し、テーブル、リスト、または拡張データを表示できます。

開発者は少なくとも2つのサイズをサポートする必要があります — Appleはsmall + mediumを推奨しています。Largeウィジェットは、アプリにそのボリュームを埋めるのに十分なコンテンツがある場合にのみ必要です。各サイズは独自のSwiftUI Viewを受け取り、WidgetKitがシステム画面にレンダリングします。重要なのは、WidgetKitはカスタムサイズをサポートしていないことです — 3つの固定サイズのみで、インターフェースの一貫性を保証します。

WidgetConfigurationによるサイズ設定

swift
struct WeatherWidget: Widget {
    let kind: String = "WeatherWidget"
    
    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: Provider()) { entry in
            WeatherWidgetView(entry: entry)
        }
        .configurationDisplayName("Weather")
        .description("Current temperature and forecast")
        .supportedFamilies([.systemSmall, .systemMedium])
    }
}

ウィジェット設定タイプ:StaticとIntent

WidgetKitは2つの設定タイプを提供します — StaticConfigurationIntentConfiguration。StaticConfigurationはすべてのユーザーに同じコンテンツを表示するウィジェットに適しています:為替レート、天気、カレンダー。IntentConfigurationは、Siriインテントシステムを通じてウィジェットを追加する際にユーザーがカスタマイズできるようにします — 例えば、天気の特定の都市や株価の特定のティッカーを選択します。

IntentConfigurationはINWidgetIntentを使用します — SiriKitのINIntentのサブクラスです。ユーザーがウィジェットを追加してパラメータ(例:都市)を選択すると、システムはこのインテントを保存し、更新のたびにTimelineProviderに渡します。プロバイダーはgetTimelineメソッドでインテントを受け取り、そのパラメータを使用してコンテンツを形成します。IntentConfigurationはSiriやShortcutsと統合されるため、パーソナライズされたウィジェットに推奨される方法です。

パラメータ選択付きIntentConfiguration

swift
struct WeatherWidgetEntryView: View {
    var entry: WeatherEntry
    
    var body: some View {
        VStack(alignment: .leading) {
            Text(entry.cityName)
                .font(.caption)
                .foregroundColor(.secondary)
            Text("\(entry.temperature)°C")
                .font(.largeTitle)
        }
    }
}

struct WeatherWidget: Widget {
    var body: some WidgetConfiguration {
        IntentConfiguration(
            kind: "WeatherWidget",
            intent: WeatherConfigIntent.self,
            provider: WeatherTimelineProvider()
        ) { entry in
            WeatherWidgetEntryView(entry: entry)
        }
    }
}

SwiftUIでのウィジェット作成:ステップバイステップの例

ウィジェットの作成は、XcodeでWidget Extension Targetを追加することから始まります:File → New → Target → Widget Extension。Xcodeは自動的にTimelineEntry、TimelineProvider、WidgetConfigurationを含む構造を生成します。開発者はデータを表示するためのSwiftUI Viewを実装し、正しい更新スケジュールのためにプロバイダーを設定するだけです。

以下は、現在のBitcoin価格を表示する簡単なウィジェットの完全な例です:ProviderはURLSessionを介してレートをロードし、1時間ごとの更新でTimelineを作成します。WidgetSwiftUIViewはレートを大きなフォントで、最後の更新時刻を小さなフォントで表示します。

swift
struct BTCPriceEntry: TimelineEntry {
    let date: Date
    let price: Double
    let change24h: Double
}

struct BTCWidgetEntryView: View {
    var entry: BTCPriceEntry
    
    var body: some View {
        VStack {
            Text("BTC/USD").font(.caption)
            Text("$\(entry.price, specifier: "%.0f")")
                .font(.title2).fontWeight(.bold)
            Text(entry.change24h > 0 ? "+" : "")
        }
    }
}

iOS 16+ロック画面ウィジェット

iOS 16以降、WidgetKitはロック画面 — iPhoneのロック画面 — のサポートを拡張しました。ロック画面ウィジェットには2つのタイプがあります:inline(時計の下の1行テキスト)とrectangular(長方形領域)。ホーム画面ウィジェットとは異なり、ロック画面ウィジェットはより頻繁に更新されます — システムトリガーにより、電話のロックを解除せずに最新情報を表示するために15~30分ごとの更新が可能です。

ロック画面ウィジェットは、accessoryFamiliesを使用したWidgetConfigurationによる個別の設定が必要です:accessoryCircular、accessoryRectangular、accessoryInline。これらのファミリには厳格なサイズとコンテンツの制限があります — 画像、アニメーション、カスタムフォントをサポートしていません。Appleはロック画面ウィジェットにはテキスト情報とSF Symbolsシステムアイコンのみを使用することを推奨しています。

  • accessoryCircular — 時計の下の領域用のコンパクトな円形ウィジェット
  • accessoryRectangular — 時計の上の領域用の長方形ウィジェット
  • accessoryInline — 時刻の下の1行テキスト、最小サイズ
  • 制限事項:テキストのみ、SF Symbols、グラデーション;画像やビデオは不可

WidgetKitのベストプラクティスと制限事項

ウィジェットを開発する際は、WidgetKitの制限事項を考慮することが重要です。ウィジェットは読み取り専用のビューです:タッチイベントを処理しません(アプリを開くタップを除く)。ウィジェットはアニメーション、ビデオ、キーボード入力、スクロール、インタラクティブ要素をサポートしていません。各ウィジェットは特定の時点でのデータの静的なスナップショットであり、インタラクティブ性を追加しようとするとApp Storeでアプリが拒否されます。

ベストプラクティスには、強制更新のためのWidget Centerの使用、迅速な応答のためのTimelineProviderレベルでのデータキャッシング、初期状態のためのプレースホルダーの使用が含まれます。また、複数のサイズをサポートすることも重要です — ユーザーはウィジェットがsmallとmediumの両方のバリエーションで利用可能であることを期待しています。不正確または古いデータの表示は厳格に避けてください — ユーザーはウィジェットからの誤った情報を長期間記憶します。

WidgetKit制限事項テーブル

許可されていないもの理由
アニメーションとビデオウィジェットは静的なスナップショットです;アニメーションはバッテリーを消耗します
インタラクティブ性WidgetKitはアプリリンク以外のUI要素をサポートしていません
スクロールスクロールなしの固定サイズ
キーボードウィジェットでのテキスト入力は不可能です
ライブデータデータはTimelineスケジュールに従って更新され、リアルタイムではありません
カスタムサイズsmall、medium、large、accessory*の固定サイズのみ

よくある質問

iOSとmacOSで1つのウィジェットを作成できますか?

はい、WidgetKitはクロスプラットフォームです。同じWidget Extensionを、単一のSwiftUIコードベースでiOS、iPadOS、macOSのターゲットに含めることができます。違いはサポートされているFamilyにのみ現れます — MacにはaccessoryRectangularがありません。

WidgetKitはどのくらいの頻度でウィジェットを更新しますか?

Timelineスケジュールに従って。開発者が次の更新がいつ行われるかを決定します — 1分後または1日後。システムは頻繁に使用されるウィジェットの更新を加速することもできます。

ウィジェットにボタンを追加できますか?

いいえ、WidgetKitはUIButtonやインタラクティブ要素をサポートしていません。唯一のアクションはウィジェットをタップすることで、ディープリンクを介してアプリを開きます。

アプリからウィジェットを強制的に更新するには?

WidgetCenter.shared.reloadAllTimelines()または特定のウィジェットにはreloadTimelines(ofKind:)を使用します。アプリからの呼び出しは即座にプロバイダーに新しいTimelineを要求します。

ウィジェットはバッテリー駆動時間に影響しますか?

最小限です — 通常の使用で1日あたり1%未満の充電です。WidgetKitはバックグラウンド更新を制限し、アプリをアクティブに保ちません。主な消費は最初の追加時のTimeline作成です。

まとめ

  • WidgetKitはiOS 14+、iPadOS 14+、macOS 11+、watchOS 10+向けのAppleのウィジェットフレームワークで、コンテンツ表示にSwiftUIを使用します。
  • TimelineProviderはTimelineEntryの配列を通じて更新スケジュールを管理し、各エントリは特定の時点でのウィジェット状態を表します。
  • Widget Familyには3つのサイズ — small、medium、large — とiOS 16+ロック画面用のaccessoryファミリが含まれます。
  • StaticConfigurationはユーザー間で同一のコンテンツに適しており、IntentConfigurationは設定付きのパーソナライズされたウィジェットに適しています。
  • ウィジェットは静的 — アニメーション、インタラクティブ性、スクロール、ビデオはありません;読み取り専用のデータ表示のみ。
  • ロック画面ウィジェット(iOS 16+)は、コンテンツ制限付きでaccessoryCircular、accessoryRectangular、accessoryInlineとして提供されます。
  • 強制更新はWidgetCenter.shared.reloadAllTimelines()を介して即座に新しいTimelineを要求できます。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください