WWDC Quick Look 💓 By SwiftGGTeam
Build custom swimming workouts with WorkoutKit

Build custom swimming workouts with WorkoutKit

元の動画を見る

ハイライト

watchOS 10 で登場した WorkoutKit は、ランニングやサイクリングなど陸上トレーニングのカスタムプラン構築に限定されていました。watchOS 11 が最大の空白を埋めました。プールスイミングです。既存の steps、goals、alerts API がすべて、スイミングアクティビティタイプでそのまま使えます。


主要内容

WorkoutKit でカスタムワークアウトを構築したことがあるなら、この壁にぶつかったはずです。ランニングとサイクリングは steps、goals、alerts を細かく編成できますが、スイミングはまったくサポートされていませんでした。ユーザーがアプリでインターバルスイムプランを設計しても、Apple Watch では手動操作しかできず、ワークアウト編成の連続性が途切れます。

watchOS 11 はカスタムワークアウトの全機能をプールスイミングに拡張しました。steps、goals、alerts API がスイミングアクティビティタイプで完全に使え、ランニング用に書いたワークアウト編成ロジックをそのまま再利用できます。さらに WorkoutKit はスイミング専用の poolSwimDistanceWithTime ゴールタイプを追加しました。スイマーは「X メートルを Y 時間以内に泳ぐ」インターバルトレーニングをよく行い、このゴールタイプは距離と時間を結び付け、両方の条件を満たしたときのみ次に進みます。

スイミング以外にも、過去 1 年で一連の段階的更新がありました。watchOS 10.1 ではワークアウトに屋内/屋外の指定が不要に。watchOS 10.4 ではランニングとサイクリングに平均パワーアラートを追加。watchOS 11 では屋内ランニングにペースアラート、より多くの屋外アクティビティタイプへの距離ゴール拡張、すべてのワークアウトタイプでのカスタムステップ名を開放。これらの変更により、WorkoutKit は「陸上競技をかろうじてカバー」から、比較的完全なワークアウト編成フレームワークへと進化しました。


詳細

プールスイミングのカスタムワークアウト

カスタムスイミングワークアウトの構造は陸上ワークアウトと完全に同じです。warmup → interval blocks → cooldown。違いは新しい poolSwimDistanceWithTime ゴールタイプで、距離と時間の両パラメータを受け取ります。

以下のコードは Session デモより(05:05):

// distance with time ゴールを作成:50 メートル + 1 分
let distanceGoal = WorkoutGoal(
    poolSwimDistanceWithTime: .init(
        distance: Measurement(value: 50, unit: UnitLength.meters),
        time: Duration.seconds(60)
    )
)

// work step に適用し、ステップ名をカスタマイズ
let workStep = WorkoutStep(
    goal: distanceGoal,
    displayName: "Freestyle"
)

// interval block に入れ、6 回繰り返す
let intervalBlock = IntervalBlock(
    workStep: workStep,
    repeats: 6
)

// ウォームアップとクールダウンのステップ
let warmupStep = WorkoutStep(
    goal: .init(distance: Measurement(value: 200, unit: UnitLength.meters)),
    displayName: "Kickboard"
)
let cooldownStep = WorkoutStep(
    goal: .init(distance: Measurement(value: 200, unit: UnitLength.meters)),
    displayName: "Free swim"
)

// プールスイミングワークアウト全体を組み立て
let swimmingWorkout = CustomWorkout(
    activity: .swimming,
    displayName: "Pool Swim Intervals",
    blocks: [
        .warmup(warmupStep),
        .interval(intervalBlock),
        .cooldown(cooldownStep)
    ]
)

// WorkoutScheduler でワークアウトをスケジュール
try await WorkoutScheduler.shared.schedule(swimmingWorkout)

キーポイント:

  • poolSwimDistanceWithTime はスイミング専用ゴールタイプで、distanceMeasurement<UnitLength>)と timeDuration)の両方が必要(05:05
  • 両ゴール達成後にのみ次ステップへ進む。距離が先に完了するとチェックマークが表示され、時間ゴール待ちであることを示す(07:30
  • displayName プロパティは watchOS 11 の新機能で、すべてのワークアウトタイプの各ステップに適用される(03:35
  • ワークアウト開始時、Apple Watch はプール長を尋ねる。実際のプール長がワークアウト設計と異なる場合、システムが距離と時間を比例スケールする(06:54

その他の更新一覧

ユーザー選択可能なロケーション(watchOS 10.1): スケジュール時に屋内/屋外の指定が必須ではなくなり、ユーザーがワークアウト開始時に決定できる(01:25)。

平均パワーアラート(watchOS 10.4): ランニングとサイクリングで averagePower アラートをサポート。現在パワーと平均パワーを区別し、範囲アラートと閾値アラートの両モードに対応(01:49)。

屋内ランニングのペースアラート(watchOS 11): 以前は屋外ランニングのみペースアラートをサポート。屋内ランニングも対応(02:06)。

距離ゴールの拡張(watchOS 11): より多くの屋外アクティビティタイプが距離ゴールをサポート。新たに outdoor rowing と outdoor skating を含む。supportsGoal 関数で特定のアクティビティ+ロケーションの組み合わせが特定ゴールタイプをサポートするか確認(02:47)。

カスタムステップ名(watchOS 11): WorkoutStepdisplayName プロパティを追加。すべてのワークアウトタイプに適用。未指定時はデフォルトでステップタイプ(「Work Step」など)を表示。名前はステップ切り替え時の全画面アラートとワークアウト中の詳細ビューに表示(03:13)。


重要ポイント

  1. スイミングインターバルトレーニングアプリを構築: poolSwimDistanceWithTime はスイマーの「時間制限付き距離」トレーニングパターンに直接対応。なぜ価値があるか: 主流トレーニングアプリのプールスイミングサポートは弱い一方、Apple Watch のスイミング追跡はハードウェアレベル(ラップ検出、水中心拍)で成熟しており、カスタムワークアウト編成と組み合わせれば Garmin など専門機器を超える体験が可能。始め方: 最もシンプルなインターバルテンプレートから。ウォームアップ + N セット「X メートル / Y 秒」+ クールダウン。WorkoutScheduler でウォッチに同期。

  2. 既存ワークアウトステップに displayName を追加: watchOS 11 の displayName はすべてのワークアウトタイプに適用。なぜ価値があるか: ワークアウト中に「Work Step 3」を見ても情報量ゼロ。「Bench Press 60kg」や「Sprint 400m」に変えると認知負荷が減り、操作ミスが減る。始め方: WorkoutStep 作成ロジックを走査し、各 step に displayName を追加。内容には種目名、重量、ペースなどのコンテキストを含められる。

  3. supportsGoal で実行時互換性チェック: watchOS 11 で距離ゴールのサポート範囲は拡大したが、アクティビティタイプとロケーションの組み合わせごとに状況が異なる。なぜ価値があるか: 「このアクティビティは距離ゴールをサポート」とハードコードすると、新システムでサポート漏れ、旧システムでクラッシュ。始め方: ゴール作成前に supportsGoal を呼び出し、戻り値に応じてそのゴールオプションを表示するか、時間/エネルギーゴールにフォールバックするか決定。


関連セッション

コメント

GitHub Issues · utterances