WWDC Quick Look 💓 By SwiftGGTeam
What's new in watchOS 11

What's new in watchOS 11

元の動画を見る

ハイライト

watchOS 11 では iOS の Live Activity が Smart Stack に自動同期され、RelevantContext API により Widget が時間やシーンに応じて自動表示されます。Interactive Widgets と AccessoryWidgetGroup テンプレートも追加され、ユーザーは Digital Crown を回すだけで App を開かずに操作を完了できます。


主要内容

Apple Watch で最も希少なリソースはユーザーの注意力です。これまで開発者が Apple Watch で露出を得る手段は 2 つだけでした。ユーザーに App を開いてもらうか、Complication の小さなスペースに押し込むかです。Complication のスペースは限られ、ユーザーは watch App を頻繁に開きません——起動率が低く滞在時間も短く、多くのチームが watchOS 版に多大な労力を注いでも、実際の利用データは厳しいものです。

watchOS 11 は新しい解決策を提示します。情報を Smart Stack に前倒しで配置することです。Digital Crown を回すだけでフライト状況、メッセージ返信、スマートホーム操作が見え、App を開くのを待つよりはるかに高い頻度で App が露出します。3 つの中核的な変化があります。

第一に、iOS の Live Activity が watch に自動同期されます。watch 側のコードは不要で、iPhone の Live Activity が Smart Stack に直接表示されます。.small family 用のカスタムビューを提供すれば、Dynamic Island のデフォルトよりカスタムコンテンツが優先されます。第二に、RelevantContext API により Widget が時間、場所、睡眠、運動などのシーンに応じて自動表示されます。開発者は TimelineProvider で「いつ Widget が最も有用か」を宣言するだけで、スケジューリングはシステムが担当します。第三に、Interactive Widgets が watchOS に登場——ボタンとトグルが Widget 上で直接機能し、App に遷移せずにドアの施錠、再生の一時停止、完了マークができます。

この 3 つを組み合わせると、戦略は明確です。watch App の起動率を最適化するより、重要な情報と操作を Smart Stack に前倒しで移すことです。

詳細

Live Activity の watch 同期(01:06

iOS App の Live Activity は watchOS 11 で Smart Stack に自動表示され、コード変更はゼロです。デフォルトでは Dynamic Island の leading と trailing ビューが使われます。より良い watch 体験のため、ActivityConfiguration.supplementalActivityFamilies 修飾子を追加し、.small family でカスタムビューを指定できます:

ActivityConfiguration(for: MyLiveActivityAttributes.self) { context in
    MyLiveActivityView(context: context)
} dynamicIsland: { context in
    DynamicIsland {
        // ...
    }
}
.supplementalActivityFamilies([.small])

キーポイント:

  • .supplementalActivityFamilies([.small]) で Live Activity が Smart Stack のコンパクトレイアウトに対応していることをシステムに伝える
  • 追加後、Dynamic Island ビューよりカスタムビューが優先される
  • Environment で .small(watch Smart Stack)と .medium(iPhone ロック画面)を区別し、レイアウトを個別にカスタマイズ可能
  • watchOS App がなくても Live Activity は watch に自動同期される

RelevantContext API(03:00

TimelineProviderrelevances() メソッドを実装し、Widget が最も有用なシーンを宣言します:

func relevances() -> WidgetRelevances<Void> {
    let dueDate = Calendar.current.date(byAdding: .hour, value: 1, to: Date())!
    let context = RelevantContext.date(dueDate...dueDate)
    return WidgetRelevances([WidgetRelevanceEntry(relevance: context)])
}

キーポイント:

  • RelevantContext.date(時間)、.location(位置)、.sleep(睡眠時間帯)、.fitness(運動状態、.activityRingsIncomplete 条件含む)など複数のコンテキストをサポート
  • AppIntentConfiguration を使う Widget では intent ごとに関連性を提供可能——例:コーヒーショップ Widget が各お気に入り店舗の位置コンテキストを提供
  • WidgetRelevanceEntry のイニシャライザは configuration パラメータを受け取り、具体的な AppIntent に関連付け
  • ユーザーが設定を変更したら invalidateRelevances() を呼び、システムに再リクエストさせる
  • システムは複数 Widget の関連性提案を同時に考慮するため、必ず表示されるとは限らない

Interactive Widgets(05:47

watchOS Widget へのインタラクション追加は iOS 17 と同じパターン——ビューに Button または Toggle を置き、対応する Intent で perform() を実装:

// Widget ビュー内
Button(intent: LockDoorIntent()) {
    Image(systemName: "lock")
}

// AppIntent 内
struct LockDoorIntent: AppIntent {
    static var title: LocalizedStringResource = "Lock Door"

    func perform() async throws -> some IntentResult {
// ドアをロックする操作を実行
        return .result()
    }
}

キーポイント:

  • すべての watchOS Widget family がインタラクションをサポート
  • 複数のインタラクティブターゲットを同一 Widget 内に配置可能(Widget の形状とサイズに制限あり)
  • 誤操作の恐れがある操作には requestConfirmation(.lowConfidenceSource) を使い、低信頼度ソース検出時に確認ダイアログを表示
  • .lowConfidenceSource はシステムが確認タイミングを判断——例:会社にいるときに自宅のドアをリモート解錠

AccessoryWidgetGroup テンプレート(07:54

watchOS 11 の新しいビューテンプレートで、accessoryRectangular Widget 用。最大 3 つのコンテンツ項目を表示:

AccessoryWidgetGroup {
    Label("Messages", systemImage: "message")
} content: {
    ContactView(name: "Alice")
    ContactView(name: "Bob")
    ContactView(name: "Charlie")
}
.accessoryWidgetGroupStyle(.circular)

キーポイント:

  • LabelContent の 2 部分構成:Label はデフォルトで Widget Extension の bundle 名を表示——カスタマイズ推奨
  • Content は最大 3 ビュー、超過分は先頭 3 つのみ表示
  • 各 Content ビューはインタラクティブ(Button)または Link で App の異なるページへ遷移可能
  • 3 未満の場合、システムが空白プレースホルダーを挿入(タップで App を開く、色は設定不可)
  • .accessoryWidgetGroupStyle(.circular) または .roundedSquare でマスク形状を制御、デフォルトは .circular
  • フォント、ビューサイズ、マージンは事前設定済み——コンテンツに集中

Double Tap の拡張(10:33

watchOS 11 では Double Tap ジェスチャーが App 内の ListScrollView、vertical TabView のスクロールを自動サポート。.handGestureShortcut(.primaryAction) で主操作を指定可能:

Button("Complete") {
    completeTask()
}
.handGestureShortcut(.primaryAction)

キーポイント:

  • ダブルタップ時、システムが Button または Toggle の輪郭をハイライトして視覚フィードバックを提供
  • ハイライト形状は clipShape でカスタマイズ可能
  • 同一時刻に primaryAction になれる要素は 1 つのみ
  • コントロールが画面内なら操作を実行、画面外なら先にスクロール
  • App が List/ScrollView 経由で自動スクロールを継承している場合、これらのビュー内のコントロールに .primaryAction を追加しない(動作競合を避ける)

WorkoutKit と HealthKit の更新(12:28

WorkoutKit にプール泳ぎのアクティビティタイプが追加され、Custom Workouts API に参加(以前はサイクリングとランニングのみ)。新しい distanceWithTime 目標タイプで 1 つのトレーニングステップに距離と時間の両方の目標を設定可能。すべてのカスタムトレーニングタイプの Warmup、Work、Recovery、Cooldown ステップが displayName プロパティでカスタム名称をサポート。

HealthKit に State of Mind API が追加され、感情と気分データの読み書きが可能。

重要ポイント

  1. Live Activity に .small ビューを提供:iOS App に Live Activity があるなら、watchOS 11 の自動同期はゼロコストの露出です。ただし Dynamic Island ビューは watch 上で情報密度が不足——.small family 用のコンパクトビューに半日投資すれば情報量が大幅に向上。始め方:既存の ActivityConfiguration.supplementalActivityFamilies([.small]) を追加し、Environment でレイアウトを区別。

  2. RelevantContext で Widget を適切なタイミングに表示:通勤、デリバリー、運動、ToDo——これらのシーンは時間や場所との関連が自然。RelevantContext の ROI は非常に高く、数行のコードでユーザーが最も情報を必要とする時に Widget を Smart Stack 上部へ。始め方:TimelineProvider で relevances() を実装し、.date または .location コンテキストから開始。

  3. AccessoryWidgetGroup でインタラクティブ Widget を素早く構築:このテンプレートはフォント、サイズ、マージンを事前設定し、最大 3 つのインタラクティブターゲットを配置——レイアウト調整の時間を大幅に削減。Messages Widget で 3 つのピン留め連絡先を表示するのが典型例。始め方:既存の accessoryRectangular レイアウトを AccessoryWidgetGroup に置き換え、.circular または .roundedSquare スタイルを選択。

  4. 重要な操作に .handGestureShortcut(.primaryAction) を追加:ユーザーが触れにくい状況(荷物を持っている、ランニング中)では Double Tap が最も効率的。App の主操作ボタンに修飾子 1 つで対応し、視覚フィードバックはシステムが処理。始め方:App で最もよく使う Button または Toggle を見つけ、.handGestureShortcut(.primaryAction) を追加。

関連セッション

コメント

GitHub Issues · utterances