← すべての記事

iOS 26のウィジェット面:1つのApp Intentが、いくつもの場所で動く

かつてウィジェットはスナップショットでした。システムがタイムラインに沿ってビューを描画し、ユーザーはそれを眺め、タップすればアプリが開く——そういうものでした。そのモデルはもう過去のものです。iOS 17以降、ウィジェットは何も起動せずにコードを実行するボタンやトグルを持てるようになり、そのコードの正体がApp Intentなのです1。コントロールセンターのコントロールも、Live Activity内のボタンも同じ仕組みです。そう気づいた瞬間、iOS 26のウィジェット面は3つの別々のAPIには見えなくなり、1つのものとして立ち現れてきます。つまり、システムがApp Intentを描画してくれる場所の集まりであって、それぞれ使える面積は違っても、土台の配管はまったく同じなのです。

この捉え直しこそが、この記事の核心です。App Intentを一度きちんと作れば、ホーム画面、ロック画面、コントロールセンター、アクションボタン、Dynamic Island、さらに(同じintentのまま)SiriとApple Intelligenceまで、すべてに火が灯ります。逆に、つながりのない機能を3つ書けば、4倍の手間をかけて、より悪い結果に行き着くだけです。

TL;DR

  • インタラクティブなウィジェット(iOS 17以降): ウィジェットのビューに Button(intent:)Toggle(isOn:intent:) を置くと、システムがウィジェット拡張内でApp Intentの perform() をアプリ外で実行し、その後タイムラインを再読み込みします1
  • コントロールセンターのコントロール(iOS 18以降): ControlWidgetButtonControlWidgetToggle から組み立てた ControlWidget は、同じApp Intentを土台にして、コントロールセンター、ロック画面、アクションボタンに姿を現します2
  • Live Activity(ActivityKit): ActivityAttributesActivityConfiguration がロック画面とDynamic Islandを駆動します。更新はサーバー主導でプッシュ経由で届き、内部のボタンもやはりApp Intentです3
  • iOS 26が加えたのは描画であって、モデルではありません: ウィジェットはLiquid Glassの見せ方とアクセント付きの描画モードを取り入れますが、「表示面としてのApp Intents」というアーキテクチャはiOS 18から変わっていません4
  • すべてを束ねる事実:ウィジェットのボタン、コントロール、Siriのフレーズ、Apple Intelligenceのアクション——これらは同じApp Intentであり得ます。能力を一度だけ設計すればよいのです。

インタラクティブなウィジェット:アプリを開かないボタン

仕組みは小さなものですが、正確に述べておく価値があります。ウィジェットのビューにSwiftUIの ButtonToggle を加えるのですが、アクションのクロージャの代わりにApp Intentを渡します1

struct WaterWidgetView: View {
    let logged: Int

    var body: some View {
        VStack {
            Text("\(logged) glasses")
            Button(intent: LogWaterIntent()) {
                Label("Add", systemImage: "plus")
            }
        }
    }
}

ユーザーがタップすると、システムはウィジェット拡張の内側で LogWaterIntent.perform() を実行します。アプリは起動しません。intentは自分の仕事をこなし(共有ストアへの書き込み、カウントの更新など)、ウィジェットのタイムラインが再読み込みされて結果が表示されます。

ToggleSetValueIntent を通じて同じように動きます。これは、ユーザーが今設定したばかりのオン/オフの値を受け取ります。

struct ToggleReminderIntent: SetValueIntent {
    static let title: LocalizedStringResource = "Toggle Reminder"

    @Parameter(title: "Enabled")
    var value: Bool

    func perform() async throws -> some IntentResult {
        ReminderStore.shared.enabled = value
        return .result()
    }
}

ウィジェットは Toggle(isOn: store.enabled, intent: ToggleReminderIntent()) をバインドし、システムが value を新しい状態にセットして perform() を実行し、再読み込みします。ボタンとまったく同じ形で、パラメータが1つ増えるだけです1

ここでできることを決めるのは2つの制約で、どちらも簡単に破ってしまえます。1つ目、perform() は実行予算の厳しいウィジェット拡張環境で動きます。これは素早い状態変更のためのものであって、ネットワークアップロードや重い計算のためのものではありません。2つ目、ウィジェットは状態を映すのであって、任意のUIをアニメーションさせるわけではありません。データを変えればタイムラインが再描画される——独自のトランジションを走らせるわけではないのです。やりとりを「値をひっくり返し、新しい値を見せる」と設計すれば、うまくいきます。それ以上を求めると、システムと戦うことになります。

コントロールセンターのコントロール:同じintent、別の部屋

iOS 18はコントロールセンター、ロック画面、アクションボタンをサードパーティのコントロールに開放しました。そのAPIは、ウィジェットと意図的に並行する設計になっています2。コントロールは ControlWidget であり、その本体はApp Intentに配線された ControlWidgetButtonControlWidgetToggle です。

struct LogWaterControl: ControlWidget {
    var body: some ControlWidgetConfiguration {
        StaticControlConfiguration(kind: "com.example.logWater") {
            ControlWidgetButton(action: LogWaterIntent()) {
                Label("Log Water", systemImage: "drop.fill")
            }
        }
    }
}

LogWaterIntent がすでにインタラクティブなウィジェットを動かしているなら、コントロールはほとんどタダ同然です。同じintentに、新しいラッパーをかぶせるだけ。これがアーキテクチャの配当です。コントロールはこの機能の2つ目の実装ではなく、すでに書いたものに対する2つ目の取り付け口にすぎません。トグルのコントロールはウィジェットのトグルとまったく同じように SetValueIntent を使うので、一度作った「ミュート」「セッション開始」「ダークモード切り替え」といった能力は、新しいロジックなしにコントロールセンター、ロック画面、アクションボタンに現れます2

Live Activity:自らを更新する表示面

Live Activityは3つ目の場所であり、動く部品が最も多い場所です。ActivityAttributes 型が静的・動的なコンテンツを定義し、ActivityConfiguration がロック画面の見せ方とDynamic Islandの各領域を描画し、ActivityKitがアクティビティを開始・更新・終了します3。Live Activity内のボタンも、やはりApp Intentです。ですからDynamic Islandの「一時停止」や「次へ」のコントロールは、ウィジェットのボタンと同じ種類のintentを実行します。

Live Activityを独自の分野たらしめているのは、更新の経路です。ローカルで更新するタイマーなら単純です。ところが、サーバー側で起きるイベント(配達状況の移動、試合スコアの変化)に駆動されるアクティビティは、プッシュ経由で更新されます。pushTokenUpdates に登録し、バックエンドからActivityKitのプッシュペイロードを送ると、システムはアプリをまったく動かさずにロック画面とDynamic Islandを更新します3。これは本当に強力であると同時に、本当に間違えやすいものです。なぜなら、いまやアクティビティの正しさが、ローカルのコードだけでなく、サーバーとの取り決め、プッシュの信頼性、そして陳腐化日時(stale-date)の方針に依存するからです。

iOS 26が実際に変えたもの

iOS 26のウィジェットの目玉は、アーキテクチャではなく見せ方です。ウィジェットはLiquid Glassの素材を取り入れ、アクセント付きの描画モードを得ます。これにより、システムの新しいデザイン言語に調和し、OSがコンテンツを再着色する文脈で正しく色づきます4。これはウィジェットがホーム画面、ロック画面、スタンバイをまたいでどう見えるかにかかわる話で、デザインを見直す価値があります。とはいえ、インタラクティブ性の動き方は変わりません。iOS 18でインタラクティブなウィジェットとコントロールを作っていたなら、iOS 26での対応は見た目のリフレッシュであって、書き直しではありません。iOS 26がインタラクティブなウィジェットを「導入した」という主張は疑ってかかりましょう。インタラクティブ性はiOS 17で、コントロールはiOS 18で出荷されており、iOS 26はそれらをシステムの他の部分と揃った見た目にしただけです。

ただし、Liquid Glassがもたらすデザイン上の含意は本物です。ウィジェットは、システムが壁紙の上に合成し、ガラスのクロムを通して屈折させるコンテンツです。ですからアプリ内のLiquid Glassを律するのと同じ規則が当てはまります。機能レイヤーとコンテンツレイヤーの重ね方を尊重し、ガラスが読み取れない重厚なカスタム背景で素材と争わないことです。

アーキテクチャを、率直に述べる

ここに、覚えておく価値のあるモデルがあります。App Intentとは、名前が付き、型が定まり、説明された能力です。iOSは、その能力を取り付けられる場所を次々と増やしています。

  • ウィジェット内の Button または Toggle
  • コントロールセンターロック画面アクションボタンにある ControlWidget
  • Live Activity とその Dynamic Island の内部にあるボタン。
  • Siri のフレーズと Shortcuts のアクション。
  • Apple Intelligence がユーザーに代わって呼び出せるアクション5

これらはどれも、perform() メソッドを持つ同じ AppIntent 型です。仕事の本体は、その能力をうまく設計することにあります。明確な名前、型付きのパラメータ、速くて冪等な perform()、そして筋の通った結果。それを一度こなせば、表示面はラッパーにすぎません。これは、App Intentこそがアプリへの本当のAPIだと論じてきたこと、そしてiOSアプリがいま晒している3つの表示面について論じてきたことと、同じ主張です。ウィジェット面はあなたが作る機能ではなく、能力が存在しさえすればそこに姿を現す場所なのです。

わざわざ作らなくてよいとき

ウィジェット面が報いてくれるのは、ひと目で分かる状態と素早いアクションを本当に持つアプリです——トラッカー、タイマー、トグル、再生中コントロールなど。何にでも報いてくれるわけではありません。

  • ひと目で分かる状態がなければ、ウィジェットも不要。 開かずに見せる価値のあるものがアプリに何もないなら、ウィジェットは保守の手間と拡張ターゲットを1つ増やすだけの飾りです。
  • 重い・遅いアクションは、ここでの perform() に置く場所ではない。 ウィジェットとコントロールの実行環境は制約が厳しいものです。アクションに本当の時間や本当の計算が必要なら、ボタンは拡張内で仕事をするふりをするのではなく、準備済みの状態でアプリを開くべきです。
  • 「ライブ」でないもののためのLive Activity。 Live Activityは時間で区切られ、能動的に変化するイベントのためのものです。常設のステータスバッジとして使うのは、この表示面の読み違いであり、アクティビティ予算をめぐってシステムのブラックリストに載る近道です。

身につけるべき技は、3つのAPIを覚えることではありません。取り付けるに値するApp Intentを設計し、それをユーザーがすでにいる場所に取り付けることです——彼らが確認するホーム画面、スワイプして開くコントロールセンター、すでに何かを見せているDynamic Islandに。能力を一度、趣味よく作りさえすれば、iOSが表示面をタダで手渡してくれます。

FAQ

iOS 26はインタラクティブなウィジェットを導入したのですか?

いいえ。インタラクティブなウィジェットはiOS 17で、コントロールセンターのコントロールはiOS 18で出荷されました。iOS 26は、それらにLiquid Glassの素材とアクセント付き描画を取り入れさせ、システムのデザイン言語と揃えただけです4。iOS 26がインタラクティブなウィジェットを「導入した」という主張は疑ってかかりましょう。iOS 26の変更は見た目のリフレッシュであって、書き直しではありません。

iOSウィジェット内のボタンは、実際にどうやって仕事をするのですか?

ボタンはApp Intentを実行します。ウィジェット内の ButtonToggle は、perform() メソッドを持つ名前付き・型付きの AppIntent を呼び出すので、ウィジェットはアプリを開かずに動きます。同じintentが、コントロールセンターのコントロール、Live Activityのボタン、Siriのフレーズ、Shortcutsのアクションを動かします5

iOS 26で、ウィジェットについて実際に変わったのは何ですか?

アーキテクチャではなく、見せ方です。ウィジェットはLiquid Glassを取り入れ、アクセント付きの描画モードを得て、ホーム画面、ロック画面、スタンバイをまたいで正しく色づきます4。インタラクティブ性はiOS 18のときとまったく同じように動くので、既存のインタラクティブなウィジェットに必要なのはデザインの見直しであって、書き直しではありません。

アプリが動いていないとき、Live Activityはどうやって更新されるのですか?

プッシュ経由です。pushTokenUpdates に登録し、バックエンドからActivityKitのプッシュペイロードを送ると、システムはアプリを動かさずにロック画面とDynamic Islandを更新します3。そのため、アクティビティの正しさは、ローカルのコードだけでなく、サーバーとの取り決め、プッシュの信頼性、陳腐化日時の方針に依存することになります。

1つのApp Intentは、どこに現れ得るのですか?

同じ AppIntent 型は、ウィジェットの Button/Toggle、コントロールセンター/ロック画面/アクションボタンの ControlWidget、Live ActivityとそのDynamic Island、Siriのフレーズ、Shortcutsのアクション、そしてApple Intelligenceが呼び出せるアクションとして取り付けられます5。能力を一度設計すれば、表示面はラッパーにすぎません。

ウィジェットやLive Activityを作らないほうがよいのは、どんなときですか?

開かずに見せる価値のある、ひと目で分かる状態がアプリにないなら、ウィジェットは見送りましょう。制約の厳しいウィジェット環境では、重い・遅いアクションを perform() に入れないこと。代わりに準備済みの状態でアプリを開きます。そして、Live Activityを常設のステータスバッジとして使わないこと。これらは時間で区切られ、能動的に変化するイベントのためのものであり、誤って使えばアクティビティ予算を浪費してしまいます。



  1. Apple Developer, “Adding interactivity to widgets and Live Activities”. インタラクティブなウィジェット(iOS 17以降)は、AppIntent(トグルの場合は SetValueIntent)を土台にしたSwiftUIの Button(intent:)Toggle(isOn:intent:) を使います。intentの perform() はアプリを起動せずにウィジェット拡張内で実行され、結果を反映するためにタイムラインが再読み込みされます。 

  2. Apple Developer, “Creating controls to perform actions across the system”ControlWidget プロトコル。コントロール(iOS 18以降)は、App Intentに配線された ControlWidgetButtonControlWidgetToggle から組み立てられ、コントロールセンター、ロック画面、アクションボタンに姿を現します。 

  3. Apple Developer, “ActivityKit”“Displaying live data with Live Activities”. ActivityAttributesActivityConfiguration がロック画面とDynamic Islandを定義・描画します。ActivityKitはアクティビティを開始・更新・終了し、サーバー主導の更新は pushTokenUpdates を用いたプッシュで行われます。 

  4. iOS 26のウィジェット描画:ウィジェットはLiquid Glassの素材とアクセント付き描画モードを取り入れ、これらは WidgetRenderingMode\.widgetRenderingMode 環境値で制御されます。インタラクティブ性のモデル(ウィジェットとコントロールにおけるApp Intents)は、iOS 17(ウィジェット)およびiOS 18(コントロール)から変わっていません。Apple, “WWDC 2025: the new software design”WidgetKit documentation。 

  5. Apple Developer, “App Intents”. 同じ AppIntent 型は、システムがSiri、Shortcuts、Spotlight、ウィジェットとコントロールの表示面、そしてApple Intelligenceを通じて晒す単位です。横断的なモデルに関する筆者の分析:App Intentsはアプリへのアップルの新しいAPIApp Intents 2とiOS 26での追加iOSアプリの3つの表示面。 

関連記事

Live Activitiesはバッジではなくステートマシンである

ReturnのLive Activityはロック画面のカウントダウンに見えますが、実態は3つの解除パスを持つ5状態のライフサイクルマシンです。本番コードとバグの記録。

4 分で読める

AppleのTranslationフレームワーク:無料、オンデバイス、そして見た目以上に切れ味鋭い

AppleのTranslationフレームワーク——translationPresentationとTranslationSessionによる無料のオンデバイス翻訳、そしてデモが省略するオフラインダウンロードの落とし穴まで。

1 分で読める

The Robots Are Taking Exams in My Search Console

First-party GSC data: 91% of 3.8M impressions fail a human-query filter. Exam questions, pasted errors, and agent sweeps…

10 分で読める