iPhoneアプリとしてウォーキングアプリを作って、健康な体を作るということをサポートしてくれるアプリがあったら嬉しいなぁ。
色々なアプリがあるけど、自分ならではのご褒美をもらえるというウォーキングアプリがあれば嬉しいなぁ。
動くことを促してくれるアプリを作って、デブ症な自分を改善したいなぁ。
Health Kitを使うと、Apple Watchとの連携についても勉強できるから一石二鳥です。
WWDC Health Kit新機能の紹介
♪ 穏やかな音楽 ヒップホップミュージック ♪ ♪
こんにちは、WWDCへようこそ 私はKarimと申します。 HealthKitのエンジニアをしています。
HealthKitフレームワークは、優れた健康体験を構築するための基盤を提供しApple Watchは、あなたを見守る多くの健康と安全に関する機能を搭載しています。
最も人気な機能は睡眠トラッキングであり、より詳細な睡眠データを取得できるようアップデートを行っています。
また、今年はHealthKitの素晴らしい新機能が追加されています。
Swiftの非同期でデータのクエリが簡潔にできるようAPIを強化しました。
より豊かなワークアウトの表現でワークアウトを向上させます。
そして眼科の処方箋のデジタルコピーなどの保存をサポートする機能を追加しています。これらの更新内容やAppでどんな活用ができるのかを説明するのを楽しみにしています。
では始めましょう睡眠は私たちの身体と心を充電するためにとても重要なことであり、Apple Watchを使って睡眠スケジュールを管理し、睡眠を理解し改善するための洞察を得ることができます。
今年は、睡眠の段階を導入することで睡眠のトラッキングをより良いものにします。Apple Watchは、あなたが眠っている際すべての異なる睡眠段階を自動的に記録してこのデータはHealthAppからアクセスでき、HealthKitに保存されます。
もちろん、Appで睡眠段階のデータを読み込み保存することも可能です。
Apple WatchやAppで 保存された睡眠データはHealthKitではsleepAnalysisという識別子を持つカテゴリーサンプルにより示されています。
レム睡眠、コア睡眠、深い睡眠、この3つの睡眠段階をサポートします。睡眠データをHealthKitに保存する際は、睡眠段階においてそれぞれの連続した期間に、1つのサンプルを作成してください。
スリープサンプル値enumは、このような感じになります。
睡眠段階を表す次の3つのケースを追加しました。
まずはAmerican Academy of Sleep Medicine(AASM)スコアリングモデル ステージ1と2に対応するsleepedCore。
次に、AASM スコアリングモデルのステージ3に対応するasleepDeep。
そして最後に急速眼球運動のステージに対応するsleepedREMです。
睡眠段階を追加したことによりasleep caseは非推奨とし、ユーザーが眠っているが睡眠段階が 特定されていないことを示すsleepedUnspecifiedを適用しました。
睡眠サンプルenumのアップデートによりHealthKitの睡眠段階のデータを保存し読み取ることが可能になりました。
各段階の睡眠サンプルを簡単に読み込むために新しい述語を追加しました。
レム段階で睡眠サンプルを読み込みたいとします。
まず初めに新しいpredicateForSamplesメソッドを使って、値としてsleepingREMを指定して述語を作成します。
これによりクエリを構築することができます。
sleepAnalysisサンプルタイプと睡眠段階の述語でクエリの述語を作成します。
このクエリ述語を使いクエリを作成することができます。このクエリを実行するとレム睡眠段階の睡眠サンプルの配列が返されます。
未特定を含むすべての睡眠段階のサンプルを読み込むことに興味がある場合、述語を構築する際に新しい.allAsleepValuesを使用できるようにAppを更新することが重要となります。
昨年からHealthKitを確認していない方には、このクエリの短い構文が見慣れないかもしれません iOS 15.4以降Swiftの非同期をサポートするためクエリAPIを更新しました。
クエリはHealthKitに不可欠な要素でありSwiftの非同期サポートにより、より簡潔な構文で使いやすくなりました。
クエリを介してHealthKitから様々なデータを読み込み述語を使って結果をフィルタリングしたり 新しいデータが入ってくるのを監視したりすることができます。
すべてのクエリは HKQueryのサブクラスです。
特定期間の総消費カロリーを知りたい場合、これらの計算された統計情報を取得するための優れたクエリがHKStatisticsCollectionQueryです。
最初の結果を得るには、クエリのinitialResultsHandlerクロージャを設定することになります。
更新を監視したい場合は、追加でstatisticsUpdateHandlerクロージャを設定します。クエリが開始されると、これらのクロージャが結果とともに呼び出されます。
Swiftの非同期のおかげでさらにシンプルにすることができます。各クエリに適合するクエリ記述子が追加されたことでHKStatisticsCollectionQueryはHKStatisticsCollectionQuery Descriptorになりました。
async result(for:)メソッドを呼び出すだけで、最初の結果が取得できます。
最初の結果を取得し 更新も監視したい場合は results(for:)を呼び出すと、AsyncSequenceが返され、それをループして結果を読み込むことができます。HealthKitはワークアウトや消費カロリーなどの関連指標をトラッキングするのに適しています。
今週の消費カロリーを調べるために統計収集のクエリ記述子を活用できます。
まず初めにカロリーサンプルに適合する述語を持つクエリ記述子を作成します。
総合計が知りたいためcumulativeSumオプションを使用します。
今週のデータに興味があるためanchorDateとしてthisSundayを使用しています。そして最後にカロリーの合計を1週間単位で計算したいと思います。
クエリ記述子を作成するとあとすべきことは result(for:)をhealthStoreオブジェクトで 呼び出すだけです。返されたstatisticsCollectionオブジェクトは、現在のデータのスナップショットを提供します。
カロリーが変化したときにライブアップデートが必要な場合 results(for:)を呼び出し、返された非同期シーケンスをループして結果を読み込むだけです。
更新の監視が終わったらループを抜けるだけでクエリが停止します。
ではここからワークアウトについて話していきましょう。HealthKitは気軽なサイクリングでもレースで自分を限界まで追い込む場合でもワークアウトとその関連指標を保存するための素晴らしい場所です。
ワークアウトにはよく 1つ以上の明確なアクティビティが 含まれています。
インターバルトレーニングで同じ運動を繰り返したり水泳、サイクリング、ランニングで構成される。トライアスロンレースに参加したりする場合もあるかと思います。
iOS 16とwatchOS 9でワークアウトAPIを更新し、これらのタイプのワークアウトと各アクティビティーの関連統計情報を取得できるようにしています。
これは、最近行った水泳/サイクリング/ランニングのワークアウトのタイムラインです。
まず水泳から始まり少し時間をあけて、サイクリングの準備をし、最後にランニングをしました 。
各アクティビティはHKWorkoutActivity オブジェクトで表現されます。
各ワークアウトアクティビティは アクティビティのタイプを含む、独自のワークアウト構成で作成されます。
ワークアウトアクティビティはアクティビティ中に発生したイベントのリストを保持します。
また各アクティビティの統計情報を読み込むことができるので、特定のアクティビティで何が起きたのかだけを分析したいときに最適です。
タイムラインに戻りましょう。
3つのアクティビティが、それぞれ適切なアクティビティタイプで構成されています。
アクティビティは時間的に、オーバーラップすることはできません。
また 各アクティビティ間で移行期間がある可能性があるため、連続している必要はありません。
移行期間中に何が起きたか分析したい場合、移行ごとに移行タイプで HKWorkoutActivityを作成できます。
これらのアクティビティはすべてworkoutActivitiesプロパティのHKWorkoutオブジェクトで、保存されます。HKWorkoutBuilderを使用してHealthKitにワークアウトを追加する場合、アクティビティの追加は、開始と終了日オプションのメタデータがある workoutConfigurationで HKWorkoutActivityオブジェクトを作成するだけで簡単にできます。
そして、ワークアウトビルダーでaddWorkoutActivityを呼び出すだけです。
Apple Watchではワークアウトセッションを使い水泳/サイクリング/ランニングのワークアウトを記録し、関連するワークアウト ビルダーを使い HealthKitにワークアウトを保存することができます。
では、私のワークアウト タイムラインに戻りましょう。
Apple Watchでこのワークアウトを記録するには、ワークアウトセッションとビルダーを設定する必要があります。
swimBikeRunタイプでワークアウトの構成を作成することから始めます。
そして、私の構成を使用してHKWorkoutSessionを作成します。
ワークアウトの開始時をセッションではstartActivityを呼び出し、関連するワークアウトビルダーではbeginCollectionを呼び出します。
これで私のセッションと ビルダーは準備ができ、水泳ワークアウトの構成と開始日を指定し、beginNewActivityメソッドを使用して、最初のアクティビティを追加できます。
各アクティビティの開始時にワークアウトビルダーのデータソースの更新を確認し回収したいデータタイプ のみ収集できます。
これは 水泳アクティビティのため水泳距離を収集したいと思います。
アクティビティ終了時に、終了日とendCurrentActivityを呼び出します。
水泳からサイクリングへの移行時の分析がしたいため水泳が終わった直後から新しく移行アクティビティを開始します。
これはアクティビティの開始時であるためビルダーデータソースを更新し水泳距離の収集は、関連性がなくなるため無効にします。
サイクリングが開始する直前に移行アクティビティを終了します。
この方法で 私の ワークアウトアクティビティのあとの部分を記録する事ができます。
ワークアウトの終了時にセッションが終了しランニング中のいかなるアクティビティも終了します。
ワークアウトビルダーを終了できHKWorkoutオブジェクトを保存し返します。
返されたワークアウトを使用してtotalEnergyBurnedやtotalDistanceのような関連するいくつかのメトリクスを読み込み、私のAppにワークアウトの概要を表示する事ができます。
しかし、このプロパティの小さなセットだけでは十分ではなくなりました。
totalSwimmingStrokeCount はすべてのワークアウトに関連しておらずワークアウトによっては、より詳細なメトリクス収集が必要です。
すべてのいかなるワークアウトに対してメトリクスの読み込みをより簡単にするために、私たちはこれらのプロパティを非推奨にし指定された定量タイプの統計を返す新しいメソッドを採用しています。
リマインドとして、この方法は\HKWorkoutActivity でも利用でき、アクティビティ中に起こったことだけにフォーカスできます。
HKWorkoutBuilderまたは HKLiveWorkoutBuilderを使用する場合にのみ、これらの統計はワークアウトで収集されたサンプルから自動的に算出されます。
このような豊富なワークアウト表現とともに分析や可視化を行う際に興味のあるワークアウトだけをクエリするのに役立つ新しい述語のセットもあります。
例を紹介します。
ここに、各アクティビティの平均心拍数が記載された私の最近のワークアウトのリストがあります。
平均心拍数が150を超えた高強度のアクティビティで自分のワークアウトを見つけたいと思います。
まず最初にワークアウトアクティビティで動作する新しいpredicateForWorkoutActivities メソッドを使って述語を作成することから始めます。
平均心拍数を毎分150回以上にしたいと思います。
次にワークアウトをクエリするためワークアウトの述語内で心拍数の述語を書き込みます。
その述語を使用してクエリを作成します。
そして クエリ記述子のresult(for: healthStore)メソッドを呼び出し述語にマッチするワークアウトのリストを取得します。
このようにして私が興味のあるワークアウトだけをクエリすることができます。
最近のワークアウトの1つに4つのランニング間隔があります。
HKWorkoutActivityを使用することはこれらの間隔をキャプチャするのに最適な方法です。
ワークアウトの間隔のすべてのアクティビティがワークアウトと同じアクティビティタイプであることを確認する必要があります。
ランニングワークアウトの場合、すべてのアクティビティは .runningタイプで構成されます。ワークアウトアクティビティを使って、間隔を記録する利点の1つは各間隔の統計情報を取得できることです。
これらのアップデートによりワークアウトには、そのアクティビティやその周辺のコンテキストをより包括的に把握できる図が含まれます。
より豊富な図を提供するためには Apple Watch Series 6 SE以降で自動的に収集される走幅やパワー(ワット)などのメトリクスである新しいランニングメトリクスを導入します。
水泳ワークアウトにおいてSWOLFスコアを追加します。ある長さで泳いだストローク数とその長さを泳ぐのにかかった 時間で定義されます。
このスコアはApple Watchに記録された水泳のワークアウトのラップイベントとセグメントイベントごとに算出されます。
これらのメトリクスはワークアウトを充実させ自身のパフォーマンスをより理解することができますが、ワークアウト後に記録される。
他の重要なメトリクスは心拍数の回復です。運動後に心拍数がどれくらい早く下がるかを推定するもので、ストレス後の心臓の回復状況を把握し健康上の問題の可能性を明らかにするために活用されます。
iOS 16では新しいCardio Recoveryのデータタイプを導入しています。
ヘルスケアAppからアクセス可能でありAppはHealthKitで、このデータを読み込み保存することができるようになります。
回復心拍数は識別子 .heartRateRecoveryOneMinute がある定量タイプです。
各回復心拍数サンプルのコンテキスト情報をメタデータとして追加することができます。
最近の水泳/サイクリング/ランニングのワークアウトでは、自身の限界まで追い込み心拍数の回復速度を観察しました。
3時間半ほどでそのワークアウトを終了しました。
ランニング時の最大心拍数が毎分184回に到達しました。
ワークアウトの次の1分間には心拍数が50回と下がりました。
Apple WatchでHKLiveWorkoutBuilderを使用した際にワークアウト後に回復心拍数サンプルと、その周辺のコンテキストがHealthKitに自動的に保存されます。
または、回復心拍数のサンプルを保存するために .heartRateRecoveryOneMinuteタイプで定量サンプルを作成します。
運動後の1分間で心拍数が50回と下がったので、それをサンプルの量として設定します。
サンプルの開始と終了日も設定します。テストタイプの回復から始めたメタデータ ディクショナリに追加のコンテキスト情報を入れます。
私はワークアウトを全力で行っていたため、テストのタイプは .maxExerciseとなります。
私のワークアウトは swimBikeRunであったため、それをアクティビティタイプとして設定しました。 HeartRateRecoveryActivity Durationキーを 使用してワークアウト時間も追加できます。
最後に、ワークアウト中に観測された最大心拍数(毎分184回)を追加します。
これらのアップデートにより水泳/サイクリング/ランニング、ワークアウトの間隔をこれまで以上に簡単に記録できるようになりました。
この新しいメトリクスの導入によりワークアウトをより包括的に把握できる図や経過過程を評価する、新たな方法を提供しています。
アクティビティやフィットネスがすべての人に影響を与える一方で視力のように多くの人に関わる健康上の側面もあります。実際、米国眼科協会によると 米国では成人の約75%が処方されたメガネやコンタクトによる視力矯正に 頼っている状況です。
これらの処方箋は失くしやすいため処方箋に沿ったメガネやコンタクトを注文するために、もう1つ予備を持っておく必要があります。私たちの電話に、それを入れましょう。
iOS 16以降からAppでメガネとコンタクトの処方箋をHealthKitに保存できるようになりました 眼科の処方箋はvisionPrescriptionTypeがあるサンプルです。
サンプルの開始日は、処方箋の発行日に終了日は有効期限に対応します。オプションとして物理的処方箋のデジタルコピーをサンプルに添付することができます。
メガネやコンタクトの処方箋のサンプルは HKVisionPrescriptionのサブクラスです。メガネの場合はHKGlassesPrescriptionサブクラス コンタクトの場合はHKContactsPrescriptionサブクラスを使用します。
各メガネの処方箋はそれぞれの目に対して1つずつ合計2つのメガネレンズ仕様オブジェクトを 使用して作成されます。
同様にコンタクトの処方箋は2つのコンタクトの仕様オブジェクトで作成されます。HealthKitに老眼鏡の処方箋を保存しましょう。
最初の段階では 1つずつの目に対して HKGlassesLensSpecification を作成します。
頂点間距離やプリズムなど一部のパラメータは、オプションです。
右目のレンズの仕様も同じように作ることができます。
右目と左目のレンズの仕様でメガネの処方箋サンプルを作成します。この処方箋は私の老眼鏡に対するものであり説明文にその旨を書き加えています。
処方箋があるhealthStoreに保存を呼び出します。
これで処方箋はHealthKitに保存されました。保存したサンプルに追加したい写真を撮りました。添付ファイルはHKAttachmentオブジェクトにあります。
HKAttachmentStoreを使用して添付ファイルを保存及び読み込みます。処方箋に添付できるのは静止画像または PDFファイルだけです。
撮影した写真を処方箋サンプルに添付するためにhealthStoreを使用してHKAttachmentStoreオブジェクトを作成することから開始します。
私の処方箋サンプルがあるaddAttachment(to:)を呼び出します。添付ファイルの名前を設定します。ここにPNGファイルを添付します。そしてファイルのURLにアクセスを取得します。
今添付した処方箋にはレンズの仕様以外にも私の氏名や生年月日など機密情報がたくさん含まれています。
HealthKitの主要原則の1つとしてプライバシーを保護し共有データを常に管理することです。
添付ファイルを含む処方箋では意図した以上のデータを共有することが容易になるため 処方箋の新しい認証モデルを導入しています。
読み取り認証は処方箋オブジェクトごとに個別に付与されます。ユーザーはAppにアクセス許可する処方箋を正確に選択しいつでもその選択を更新することができます。
眼科の処方箋オブジェクトの認証を要求するための新しいAPIを用意しました。
他のデータタイプのようにあなたのAppからアクセスする処方箋を読み込むためにクエリを使用します。特定の処方箋にだけ興味がある場合、述語を使用できます。認証リクエストをするためにvisionTypeで healthStoreの requestPerObjectRead Authorization メソッドを呼び出します。
そうすることで 常にAppに 認証プロンプトが表示され述語に一致するすべての処方箋のリストが表示されます。
最高のユーザー体験を保証するために 適切なコンテキストで認証を確認してください。
これらは あなたのAppがより良い健康とフィットネス体験を提供できるためにHealthKitに追加された新しくなった部分です。
皆さまが次にどのようなものを構築するか楽しみにしています。WWDCで素晴らしい日々を!
ご質問がある場合は Developer Forumで皆さまのお手伝いが できればと思います ♪
HealthKitでウォーキングアプリの要件を洗い出す
2023年の目標は一回の運動で10kmを走ることにしました。
その時に使うウォーキングアプリが欲しい。このため、AppleのHealthKitを使ったウォーキングアプリで、Apple WatchとiPhoneを連動した機能を作りたいと思います。
SwiftUI HealthKitでウォーキングアプリの要件を洗い出す
SwiftUIを使用してiPhone上でHealthKitを統合してウォーキングアプリを実装する手順を説明します。
HealthKitを使用することで、ユーザーの健康データを取得し、ウォーキングや運動の情報をトラッキングできます。以下は基本的なステップです。
- Xcodeプロジェクトのセットアップ:
- 新しい SwiftUI プロジェクトを作成します。
- HealthKitを使用するために、プロジェクトにHealthKitフレームワークを追加します。
- HealthKitの許可を要求する: ユーザーにHealthKitデータへのアクセス許可を求めるために、Info.plistファイルに以下のキーを追加します。
NSHealthShareUsageDescription
: 読み取りアクセスの説明NSHealthUpdateUsageDescription
: 書き込みアクセスの説明
- HealthKitデータの読み取り: HealthKitを使用して歩数や運動データを読み取りたい場合、HealthKitデータストアからデータを取得します。例えば、歩数データを読み取るコードは以下のようになります。
- ユーザーインターフェースの構築: SwiftUIを使用してウォーキングアプリのユーザーインターフェースを構築します。これには歩数を表示するビュー、運動データのチャート、ボタンなどが含まれます。
- データの表示と更新: 取得したHealthKitデータをUIに表示し、リアルタイムでデータを更新します。SwiftUIには、
@State
や@Binding
を使用してUI要素とデータを結びつける機能が備わっています。
これらのステップを組み合わせて、HealthKitを使用したウォーキングアプリを作成できます。アプリ内でデータを収集、表示し、ユーザーにとって使いやすく魅力的なものにするために、UIデザインや他の機能も検討してください。
import HealthKit
let healthStore = HKHealthStore()
func requestAuthorization() {
let typesToRead: Set<HKObjectType> = [HKObjectType.quantityType(forIdentifier: .stepCount)!]
healthStore.requestAuthorization(toShare: nil, read: typesToRead) { (success, error) in
if success {
// アクセスが許可された場合の処理
} else {
// アクセスが拒否またはエラーが発生した場合の処理
}
}
}
func getStepCount() {
guard let stepCountType = HKObjectType.quantityType(forIdentifier: .stepCount) else { return }
let query = HKSampleQuery(sampleType: stepCountType, predicate: nil, limit: HKObjectQueryNoLimit, sortDescriptors: nil) { (query, results, error) in
if let result = results?.last as? HKQuantitySample {
let stepCount = result.quantity.doubleValue(for: HKUnit.count())
// 歩数データを取得
}
}
healthStore.execute(query)
}
コメント