WWDC Quick Look 💓 By SwiftGGTeam
What's new in HealthKit

What's new in HealthKit

元の動画を見る

ハイライト

HealthKit エンジニアの Karim が、iOS 16 と watchOS 9 の HealthKit における4つの主要アップデートを紹介します。睡眠ステージの追跡、Swift async クエリ API、トライアスロンなどのマルチアクティビティワークアウトの強化表現、視力処方のデジタル保存です。

主要内容

健康 App では、データの粒度が足りないことがよく問題になります。睡眠 App はユーザーが「眠った」ことしか分からず、REM、コア睡眠、深い睡眠を区別しにくい。ワークアウト App は1回のトレーニングは保存できても、トライアスロンの水泳・自転車・ランニングと中間の換装を分解して分析しにくい。メガネ App は紙の処方箋、写真、フォームの間で情報を行き来させます。

iOS 16 と watchOS 9 はこれらの問題を HealthKit のデータモデルに取り込みました。Apple Watch が睡眠ステージを自動記録し、HealthKit クエリは Swift async に対応。Workout API は HKWorkoutActivity で1回のワークアウト内の複数アクティビティを表現し、視力処方は HealthKit サンプルとして保存でき、静止画や PDF を添付できます。

価値は、App が独自フォーマットを少なく保ち、システムレベルの健康データを再利用できることです。睡眠ステージ、ワークアウトの区間、心拍回復、メガネとコンタクトレンズの処方はすべて HealthKit の権限モデルに従います。ユーザーは引き続き認可範囲を制御し、開発者は実際のシナリオに近いデータ構造を得られます。

睡眠:「眠り」から具体的なステージへ

睡眠データを読むとき、以前は .asleep でユーザーが睡眠中であることを表せば十分でした。Apple Watch は睡眠を REM、コア、深い睡眠の3ステージに分けます。HealthKit は .asleepCore.asleepDeep.asleepREM を追加し、古い .asleep はステージ未指定の睡眠を表す .asleepUnspecified に置き換えられました。

保存時は、同じ睡眠ステージの連続区間ごとに独立した sleepAnalysis カテゴリサンプルを作成します。すべての睡眠ステージを読むとき、.asleep だけを検索する旧コードは新しいステージ値を見逃すため、.allAsleepValues に切り替える必要があります。

ワークアウト:1回の workout に複数のアクティビティ

トライアスロンは1つの連続した「運動タイプ」ではありません。水泳、換装、自転車、換装、ランニングがあります。HealthKit の新しい HKWorkoutActivity はこのタイムライン向けです。各 activity には独自の workout configuration、イベント、統計があります。activity 同士は重複できませんが、首尾を接する必要はなく、換装時間は .transition で個別に記録できます。

Apple Watch では HKWorkoutSession がリアルタイム追跡を担当し、関連する workout builder が HealthKit にデータを書き込みます。新しい activity に入るたびに App は beginNewActivity を呼び、builder data source を更新して現在のアクティビティに必要なデータだけを収集します。例えば水泳中は水泳距離を収集し、換装中は無効にします。

処方:HealthKit が視力情報と添付ファイルを保存

メガネやコンタクトレンズの処方は紛失しやすく、名前や生年月日などの機微情報を含むことも多いです。iOS 16 では App が視力処方を HealthKit サンプルとして保存できます。メガネは HKGlassesPrescription、コンタクトは HKContactsPrescription。処方の開始日は発行日、終了日は有効期限に対応します。

ユーザーが紙の処方を持っている場合、App は HKAttachmentStore で処方サンプルに静止画や PDF を添付できます。読み取り権限は処方オブジェクトごとに認可され、ユーザーは App に開放する処方を選択でき、いつでも変更できます。

詳細

睡眠ステージの読み書き

01:33)Apple Watch は睡眠ステージを自動追跡し、HealthKit に保存します。App もこれらのステージを読み書きできます。講演では3つのステージ値を明示:.asleepCore.asleepDeep.asleepREM

以下は transcript から整理した呼び出し順の示意。Session が提供する完全なコードではありません。

1. 読み取る睡眠ステージを選択。例:asleepREM。
2. predicateForSamples で睡眠ステージ predicate を作成。
3. sleepAnalysis サンプルタイプとステージ predicate をクエリ条件に組み合わせる。
4. Swift async の result(for:) でクエリを実行し、REM ステージの sleep サンプルを取得。

キーポイント:

  • asleepREM で REM ステージを選択。
  • predicateForSamples は講演で言及された新しい predicate。睡眠ステージでサンプルをフィルタ。
  • sleepAnalysis は HealthKit で睡眠カテゴリサンプルを保存する identifier。
  • result(for:) は Swift async クエリの入口。一致する睡眠サンプルを返す。

04:13)すべての睡眠ステージを読みたい場合、クエリ条件は新しいステージ値と未指定ステージをカバーする必要があります。講演では .allAsleepValues の使用を要求。

以下は transcript から整理した呼び出し順の示意。Session が提供する完全なコードではありません。

1. allAsleepValues ですべての睡眠ステージと unspecified を表す。
2. predicateForSamples ですべての asleep values をカバーする predicate を作成。
3. Swift async で sleepAnalysis サンプルをクエリ。
4. サンプル value で REM、コア、深い睡眠、unspecified を区別。

キーポイント:

  • .allAsleepValues には REM、コア、深い睡眠、unspecified が含まれる。
  • 古い .asleep は非推奨。継続使用するとステージデータを見逃す。
  • 各連続ステージは個別サンプルとして保存。読み取り結果は自然に時間区間になる。

Swift async で HealthKit をクエリ

04:36)HealthKit クエリはクロージャコールバックから query descriptor へ移行。HKStatisticsCollectionQueryHKStatisticsCollectionQueryDescriptor に対応。現在の結果だけ必要なら result(for:)。更新の監視を続けるなら results(for:) を呼び、AsyncSequence を返す。

以下は transcript から整理した呼び出し順の示意。Session が提供する完全なコードではありません。

1. statistics collection query descriptor を作成。
2. predicate はカロリーサンプルにマッチ。
3. options は cumulativeSum で総量を統計。
4. anchorDate は thisSunday、interval は1週間。
5. result(for:) で現在の statistics collection を取得。
6. 継続更新が必要なら results(for:) の AsyncSequence を反復。
7. 監視をやめるときループを抜け、クエリを停止。

キーポイント:

  • HKStatisticsCollectionQueryDescriptor は旧 HKStatisticsCollectionQuery に対応。
  • .cumulativeSum で期間内の総量を計算。講演では今週消費カロリーの統計に使用。
  • anchorDateintervalComponents で統計区間を決定。例は1週間。
  • result(for:) は一度きりのスナップショット。
  • results(for:) は反復可能な更新ストリーム。ループを抜けるとクエリ停止。

マルチアクティビティ workout と区間統計

07:32)iOS 16 と watchOS 9 の Workout API はマルチアクティビティトレーニングを表現できます。各 HKWorkoutActivity には独自の HKWorkoutConfiguration があり、HKWorkout.workoutActivities に保存されます。

以下は transcript から整理した呼び出し順の示意。Session が提供する完全なコードではありません。

1. 水泳区間用の workout configuration を準備。activity type は swimming。
2. その configuration、start date、end date、任意の metadata で HKWorkoutActivity を作成。
3. この activity を workout builder に追加。
4. 自転車、ランニング、transition 区間でも同様に繰り返す。

キーポイント:

  • workout configuration でその区間の activity type を指定。
  • start date と end date で activity の時間範囲を定義。
  • activity は重複不可。換装時間には空きを残せる。
  • addWorkoutActivity で区間を workout builder に書き込み、最終的に HKWorkout とともに保存。

10:21)Apple Watch 上のリアルタイム記録フロー:swimBikeRun タイプの workout session を作成し、session と builder を開始。各区間開始時に beginNewActivity を呼ぶ。

以下は transcript から整理した呼び出し順の示意。Session が提供する完全なコードではありません。

1. swimBikeRun workout configuration で HKWorkoutSession を作成。
2. workout 開始時に session の activity を開始。
3. 関連する workout builder の collection も同時に開始。
4. 水泳開始時に beginNewActivity を呼び、swimming configuration と開始時刻を渡す。
5. builder data source を更新し、水泳距離など現在区間に必要なデータだけを収集。
6. 水泳終了時に endCurrentActivity を呼ぶ。
7. 換装時間を分析するなら、すぐ transition activity を開始し、水泳距離収集をオフ。
8. 自転車とランニング区間でも同様に切り替え。
9. workout 終了時に session を終了し、workout builder を finish して HKWorkout を保存。

キーポイント:

  • startActivitybeginCollection がワークアウト全体の開始をマーク。
  • beginNewActivity で新しいアクティビティ区間に切り替え。
  • 各区間開始時に builder data source を更新し、現在のアクティビティ関連データだけを収集。
  • endCurrentActivity で現在のアクティビティを終了。ワークアウト全体終了時、session はまだ動いている activity も終了。

12:29totalEnergyBurnedtotalDistancetotalSwimmingStrokeCount などの固定プロパティはすべての workout に合わなくなりました。HealthKit は quantity type ごとに statistics を返すメソッドを提供し、HKWorkoutHKWorkoutActivity の両方で使えます。

以下は transcript から整理した呼び出し順の示意。Session が提供する完全なコードではありません。

1. 読み取る quantity type を選択。例:distance や heart rate。
2. HKWorkout 上でその quantity type の statistics をリクエスト。ワークアウト全体の統計。
3. ある HKWorkoutActivity 上で同じ quantity type の statistics をリクエスト。その区間の統計。
4. 区間 statistics で分析や可視化を駆動。

キーポイント:

  • statistics(for:) で quantity type ごとの統計を読み取る。
  • HKWorkout 上では範囲はワークアウト全体。
  • HKWorkoutActivity 上では範囲が特定のアクティビティ区間に狭まる。
  • これらの statistics は workout builder または live workout builder が収集したサンプル由来。

心拍回復と新しいワークアウト指標

15:14)Apple Watch Series 6、SE、以降の機種は stride length や power などの新しいランニング指標を自動収集。水泳 workout には SWOLF スコアが追加され、lap event と segment event ごとに計算。

16:23)iOS 16 に Cardio Recovery データタイプが追加。HealthKit identifier は .heartRateRecoveryOneMinuteHKLiveWorkoutBuilder を使うと、ワークアウト終了後に心拍回復サンプルとコンテキストが自動保存。

以下は transcript から整理した呼び出し順の示意。Session が提供する完全なコードではありません。

1. heartRateRecoveryOneMinute quantity type を選択。
2. 運動後1分の心拍下降値を記録。講演例は50 beats per minute。
3. サンプルの start date と end date を設定。
4. metadata に recovery test type を追加。例は maxExercise。
5. metadata に activity type を追加。例は swimBikeRun。
6. metadata に workout duration と maximum heart rate を追加。講演例の最高心拍は184。
7. heart rate recovery quantity サンプルを保存。

キーポイント:

  • .heartRateRecoveryOneMinute は運動後1分の心拍下降値。
  • 例の 50 は講演ケース:運動後1分で心拍が50回下降。
  • metadata にテストタイプ、運動タイプ、運動時間、最高心拍を保存。
  • .maxExercise は全力運動からの回復テストを意味。

視力処方と添付ファイルの認可

19:31)視力処方は HealthKit では visionPrescriptionType サンプル。メガネ処方は HKGlassesPrescription、コンタクト処方は HKContactsPrescription。各処方は左右の lens specification で構成。

以下は transcript から整理した呼び出し順の示意。Session が提供する完全なコードではありません。

1. 左眼用の glasses lens specification を作成。
2. 右眼用の glasses lens specification を作成。
3. 左右の specification で glasses prescription サンプルを作成。
4. prescription の start date は発行日。
5. prescription の end date は有効期限。
6. 老眼鏡なら用途を description に書き込む。
7. HealthKit に prescription サンプルを保存。

キーポイント:

  • HKGlassesLensSpecification は片目のレンズパラメータを保存。
  • HKGlassesPrescription は左右の仕様を1枚のメガネ処方にまとめる。
  • start date は発行日、end date は有効期限。
  • description に「reading glasses」などの用途を記録可能。

21:25)処方サンプルに静止画や PDF を添付可能。添付は HKAttachment で表し、HKAttachmentStore で保存・読み取り。

以下は transcript から整理した呼び出し順の示意。Session が提供する完全なコードではありません。

1. healthStore で HKAttachmentStore を作成。
2. すでに保存済みの prescription サンプルを選択。
3. attachment name を設定。例:Prescription.png。
4. 静止画または PDF ファイルの URL を渡す。
5. prescription サンプルに attachment を追加。

キーポイント:

  • HKAttachmentStore は同じ healthStore で作成する必要がある。
  • addAttachment(to:) ですでに保存済みの prescription サンプルにファイルを紐づけ。
  • HealthKit は処方への添付として静止画または PDF のみ許可。
  • 処方添付には名前や生年月日などの機微情報が含まれる可能性。読み取り権限は処方オブジェクトごと。

23:07)処方の読み取りをリクエストするとき、App は requestPerObjectReadAuthorization を呼ぶ。システムは predicate に一致する処方リストを表示し、ユーザーが App に読み取りを許可するオブジェクトを選択。

以下は transcript から整理した呼び出し順の示意。Session が提供する完全なコードではありません。

1. vision prescription type を準備。
2. 一部の処方だけ必要なら、先に predicate を準備。
3. requestPerObjectReadAuthorization を呼び、一致する prescription objects の読み取りをリクエスト。
4. システムが処方リストを表示。ユーザーが App に読み取りを許可するオブジェクトを選択。
5. HealthKit クエリで App が読み取り権限を得た処方を読み取る。

キーポイント:

  • 認可範囲は処方タイプ全体ではなく各 prescription object 単位。
  • predicate で現在のタスクに関連する処方に認可リクエストを限定可能。
  • 認可プロンプトは常に表示される。ユーザーが明示的に処方をインポート・選択する文脈に置くのが適切。
  • クエリは App が読み取り権限を得た処方だけを返す。

重要ポイント

1. 睡眠ステージトレンドカード

  • やること:直近7日間の REM、コア、深い睡眠の時間変化をユーザーに表示。
  • 価値:watchOS 9 は睡眠ステージを HealthKit に保存。App が独自にステージを推測する必要がない。
  • 始め方sleepAnalysis.allAsleepValues でクエリし、サンプル value でグループ化。Swift Charts で積み上げ棒グラフ。

2. トライアスロン復習ページ

  • やること:1回の swim-bike-run workout を水泳、換装、自転車、ランニングに分割し、各区間のペース、距離、心拍を表示。
  • 価値HKWorkoutActivity で1回の workout に複数区間構造。区間 statistics は HealthKit から直接取得可能。
  • 始め方HKWorkout.workoutActivities を読み取り、各 activity で statistics(for:) を呼ぶ。.transition 区間は個別にマーク。

3. インターバルランニング分析

  • やること:ランニング workout の各 interval の平均心拍、距離、回復状況を表示。
  • 価値:講演は interval workout に同じ activity type の複数 HKWorkoutActivity を使うことを推奨。
  • 始め方:running workout の activities を interval リストとして扱い、各区間の心拍・距離 statistics を読み取り、.heartRateRecoveryOneMinute と関連付け。

4. 視力処方の金庫

  • やること:ユーザーがメガネとコンタクトレンズの処方を保存し、クリニックから受け取った画像や PDF を添付できるようにする。
  • 価値:iOS 16 は HKGlassesPrescriptionHKContactsPrescription、処方添付をサポート。
  • 始め方:左右の lens specification で prescription サンプルを作成。保存後 HKAttachmentStore で画像や PDF を追加。

5. 処方のオンデマンド共有フロー

  • やること:ユーザーがメガネを購入するとき、使用する処方だけの読み取りをリクエスト。
  • 価値:HealthKit の処方読み取り認可は per-object。全処方を一度に読む必要がない。
  • 始め方:「処方を選択」ボタンの後に requestPerObjectReadAuthorization を呼ぶ。predicate で候補を限定し、認可後のクエリ結果を表示。

関連セッション

コメント

GitHub Issues · utterances