ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
ヘルスデータをHealthKitに同期する
HealthKitがあれば、iPhoneやApple WatchのようなHealthKit仕様のデバイスであれ、外部サーバーであれ、どこであってもスマートにヘルスデータを管理し、医療チームとデータシェアができます。このセッションではHealthKitにビルトインのsyncアイデンテイファイアのメタデータを使い、データバージョンを管理する方法、HKAnchoredObjectQueryを使いヘルスデータの変化を検知する方法をお伝えし、どこにいても常に正しいデータを使うことができるようになるための成功事例もお見せします。
リソース
関連ビデオ
WWDC23
WWDC20
-
ダウンロード
こんにちは ようこそWWDCへ “ヘルスデータをHealthKitに同期する” “ヘルスデータをHealthKitに同期する” へようこそ 私はネトラ HealthKitチームの ソフトウェア開発者です ユーザーは最も内密で個人的な情報を 健康データとしてデバイスに保存しています Appleのプラットフォーム上で HealthKitは健康データへの アクセスを簡単にする基盤です アプリケーションに構築された すべての豊かな体験を可能にします つまり私たちは ユーザーに力を与える 大きなヘルスエコシステムの一部です ユーザーはエコシステムの どこからでも健康データにアクセスできます Apple WatchやAppleからリリースされた 幅広いアプリケーションからです ユーザーのデータに変更を加えるなどして 驚かせたくありません ヘルスエコシステムの よいメンバーでいるのは大変です ここでご紹介するHealthKitが きっと役立つでしょう 目標はユーザーに力を与えることです データは常にユーザーの管理下にあり その変更は常に ユーザーの意図を反映すべきです セッションの要点は2つです 最初にHealthKit内の変更のモニター データはヘルスエコシステムの どこからでも読み書き可能です 多様なアプリケーションの実行や データの視覚化に使えます HealthKit内の変更に適応するよう アプリケーションは備えが必要です
次にHealthKitと同期した 外部のデータストアの維持と それが いかに容易か見ていきます
まずHealthKitの変更のモニターからです このコンセプトで機能する アプリケーションを構築しましょう これは けがから回復中の患者向けで 患者は毎日の歩数を把握できます 時と共に患者は 日々の成果をモニターしたいと考えます また彼らは週に2回 理学療法士に会い ある歩行テストを行います 6分間で歩ける距離のテストです 患者が平らな場所を歩いて 6分間で進める距離を測ります 理学療法士がテスト結果を入力すると データは週間レポートとして ユーザーのiPhoneに同期されます
こうした重要なデータのモニターには グラフが最適です 患者は実際の値を過度に気にせず 歩数の経過を一目で見られます 患者と理学療法士の双方が グラフに関心を示します それは過去1週間の 1日ごとの総歩数を追跡します 歩数はApple WatchとiPhoneから記録可能です 1日の正確な歩数を 確実に得られるべきです このようなグラフを作るには まずHKStatisticsCollectionQueryです 多くのグラフ作成時に行うべき 最初のクエリです これについては“HealthKit入門”を ご覧の方はご存じでしょう まだ見ていない方は 先に ご視聴をお薦めします そのセッションで作ったアプリケーションを 後ほど使用する予定です 先ほど作成したグラフが リモートサーバに送られると ユーザーの経過に関心のある 理学療法士もグラフを見られます 表示方法は?
まず その週の初期グラフをサーバに送ります
次に より多くの歩数が集計されるなど データに何か変更があれば 新しいデータが サーバに送られる必要があります ここでは外部データを リモートサーバと見なしていますが デバイス上でローカルに維持される 外部データベースの場合もあり得ます Core DataやSQLiteデータベース使用の 可能性もあります
私たちはHKStatisticsCollectionQueryで データをロードできますが 新たなデータ取得には 定期的なクエリの実行が必要でしょう 恐らくアプリケーションの起動時と その後 数時間ごとにです 新たな変更への反応として そこにはマイナス面もあります データが あまり変更されない場合 HKStatisticsCollectionQueryを何度も実行し 余分な計算をすることになります
また毎回 全データを送ることになり ネットワークリソースの無駄です HealthKitには こうしたケースのために別のツールがあり HKAnchoredObjectQueryと呼ばれます HKAnchoredObjectQueryにより 健康データベースの更新をモニター可能です 健康データベース内の変更が スナップショットで示され それは新しいサンプルと 削除されたサンプルを含みます ではクエリの話です
アンカー付きオブジェクトのクエリは アンカーを必要とします アンカーは健康データベースの進展の ある時点を表します 健康データはこの時点以降で 追加や削除されます
クエリから最後に受信した全サンプルを アンカーにより特定可能です HealthKitにアンカーを与えた場合 その時点以降の変更のみを返します
最初のクエリに対するアンカーはnilになります この時点でのHealthKitは A B Cのサンプルを持っています
クエリを実行すると指定のデータタイプに基づき 全データを返します ここではupdateHandlerで サンプルA B Cを受信します アンカーは更新されHealthKitは updateHandlerに新しいアンカーを付けます
そこがサンプルを入れて返した 直近の時点となります
updateHandlerの最後の呼び出し後 さらにサンプルが追加されたとしましょう これらはサンプルDとEを含み サンプルBは削除されているとします 後続のクエリが実行されると 直前のアンカー以降の変更だけが返されます サンプルDとE サンプルBの削除を含み AとCの情報はありません
HKAnchoredObjectQueryや HealthKitのどんなクエリを使う時も 扱うデータのタイプとユースケースへの 考慮が必要です 歩数の場合では サンプル自体は気に掛けません Apple Watchは 5年前に発売されており これらのデバイスによる大量のデータを 同期させることになります 私たちに必要なのは累計の統計値で 個々のサンプルではありません 他のケースでは個々のサンプルを 重視する時もあります あまり頻繁に得られないサンプルの場合は 各データタイプの取り扱いは違うでしょう クエリやデータの同期方法について 少し考えてみましょう 実行したいクエリのタイプは 遂行するタスクで決まります
最小限のデータのクエリは パフォーマンスで有利にもなります このユースケースでは 理学療法士用の統計グラフが欲しいだけです では 得る方法は? HKAnchoredObjectQueryのサンプルを見れば グラフを計算できます 2つのクエリを連動させない理由は? アンカー付きオブジェクトのクエリで 属性とサンプルタイプを希望通りに設定できます HealthKit内の変更が更新される場合
統計値の収集クエリの作成と実行に 返されたサンプルの日付を使えます
その統計値は更新されたグラフデータとして リモートコンピュータに送信できます 新しいデータをサーバへ送りました これはローカルなCore Data modelや NSURLSessionの場合もあり得ます よりよく理解するために コードを見てみましょう
まずアンカー付きオブジェクトのクエリに パラメータを設定 サンプルタイプは歩数です アンカーパラメータは PersistedAnchorを使います アンカーを持続すると 最後のクエリ以降の変更だけ回収できます
initialResultsHandlerとupdateHandlerに 同じ動作が必要なので ハンドラー変数として 同じブロックを設定します
ハンドラー内で HealthKitから返されたサンプルをアンラップ
サンプルから属性を作成します これはサンプルが回収された日付などです 統計値を集めるクエリの初期化に使います
ここでPersistedAnchorの更新も必要です
ブロックの最後で その属性を使い fetchStatisticsメソッドを呼び出せます これがHKStatisticsCollectionQueryを作ります
HKAnchoredObjectQueryを 設定したパラメータで初期化 これらはサンプルタイプ nil属性 アンカー resultsHandler updateHandlerを含みます
最後にhealthStore上でクエリを実行します
次に HKStatisticsCollectionQueryの fetchStatisticsメソッドによる作成です 再度パラメータを設定 数日分まとめた統計値の収集クエリが必要です アンカーの日付を月曜の真夜中にし 間隔のパラメータを1日に設定します サンプルタイプは ここでも歩数です
HKStatisticsCollectionQueryを このパラメータで初期化できます 1日ごとの総歩数を求めるので オプションは累積和とします アンカー付きオブジェクトに作られた 属性を規定しました
initialResultsHandler内で statisticsCollectionをアンラップし このデータをリモートサーバへ送ります
するとhealthStore上で クエリを実行後の更新だけが得られます
HealthKitから外部のサーバへの データ送信は以上です 次は 外部記憶装置からのデータ受信と HealthKitへの保存についてです 患者は週に2回 理学療法士を訪問し 6分間の歩行テストをするんでしたね 歩行テストは患者が平らな場所を 6分間で歩ける距離の測定で 患者の運動能力を見極めるのに よく使われる方法です 今年はHealthKitに 新たなモビリティタイプを導入しました データタイプの1つである 6分間の歩行テストの距離は 私たちのアプリケーションに最適です 歩行テストのサンプルとして 理学療法士から受信したデータを保存できます 理学療法士はAppに歩行テストの値を記録し 週間レポートは患者のデバイスと同期します 週間レポートは日ごとの歩行距離による グラフを含みます
またその下にグラフから得た 個別のサンプルが表示されます 理学療法士や患者が 個別のテスト結果を掘り下げるためです これが各データタイプに 異なる扱いが必要なケースです 扱うデータタイプやユースケースに 配慮が要ります sixMinuteWalkTestDistanceは HealthKitに あまり頻繁には書き込まれませんし 患者や理学療法士は個別のテストサンプルに 興味があるかもしれません そのためこのグラフでは 個々のサンプルをプロットする価値があります 先ほど歩数のサンプルをデバイスから リモートサーバへ同期させました 今は この週間レポートを 理学療法士のサーバに置いています これを患者のデバイスに同期するのに 該当サンプルをHealthKitに保存します
すると患者は個別のテストサンプルと共に sixMinuteWalkTestDistanceグラフを見られます HealthKitに変更を保存する時の 注意点は2つです HealthKitには増分サンプルのみ保存します 全データを削除し保存し直すと 健康データに矛盾が生じることがあります 新しいサンプルは 最新の健康データを反映します 例えば 新しい6分間の歩行テストや歩数 体重の変更さえ反映するでしょう
サンプルを削除する際は そのアプリケーションで 書き込まれたものだとの確認が必要です あなたが保存したデータしか 削除できません まずサンプルにクエリを出してから 削除するのが効率的です
サンプルの追加や削除には ユーザーの意図を反映すべきです ユーザーにサンプル削除の意図がなければ 削除されるべきではありません
さて ここで課題が生まれます 理学療法士がテストを 更新したい時はどうでしょう? 例えば6月18日の6分間歩行テストで 患者が400メートル歩いたとします 理学療法士が後でデータを更新すると エラーを示します 実際に歩いた距離は 450メートルだったのです これは少し厄介です 削除してから新しいサンプルを加えないと 重複して保存することになり得ます つまりサンプルにクエリを実行し 編集済みのサンプルと一致させてから 新たなものを保存するということです 他のサンプルを編集する必要がなければ 変更中に 他に重複したサンプルを 保存しないよう確認が要ります 健康データはiPhoneやApple Watchなど 患者が所有する全デバイスで入手可能です サンプルの変更は全デバイスで 正確に反映される必要があります 1台のデバイスにサンプルを保存したら 他のデバイスで同じものを 保存しないでください そしてユーザーの意図が 正しく反映されるよう確実にします 複雑に見えますが HealthKitは実に容易にします HealthKitは2つのメタデータキーを含みます HKMetadataSyncIdentifierと HKMetadataSyncVersionです 同期識別子は文字列 バージョンは数で表されます 識別子により複数のデバイスにわたり ヘルスエコシステム内のどこからでも サンプルを認識できます バージョンにより サンプルが 更新されたタイミングが分かります
同期識別子をサンプルに設定すると HealthKitは重複するコピーが 健康データベースにないか確かめます 同期識別子とバージョンの組み合わせで バージョンの数字が増えた時だけ サンプルを更新するようにできます さらに同期識別子による 全オペレーションはトランザクションセーフです つまりエラーがあった場合 データは矛盾がない状態だと確認できます 健康データはユーザーの どのデバイスでも入手可能です 同期識別子でサンプルを デバイス間で一貫した状態に保てます リモートサーバに1つの識別子と バージョン1のサンプルがあります サンプルは ここから 患者のiPhoneへ同期されます これを最初のサンプルとして HealthKitは保存できます
HealthKitは新しいサンプルの保存を認識すると 患者の全デバイスに同期させます Apple Watchを持っていれば そこにも同期されます
リモートサーバもWatchとデータを同期させ サンプルを保存しようとすると HealthKitは 存在を認識し そのサンプルを無視します 理学療法士が6分間の歩行テストの 距離のデータを更新する場合 同期識別子を一貫した状態に保つことで サンプルを更新しますが バージョン番号は増やします
サンプルが患者のデバイスと同期する時 HealthKitはバージョン番号の更新を知らせて 新しいサンプルで上書きします
そして再度 患者の全デバイスと同期します
リモートサーバがApple Watchと バージョン2のサンプルを同期すると HealthKitはサンプルが既存だと認識し それを無視します 保存と同期において HealthKitはすべての競合を解決します バージョン管理と同期という難しいタスクは 矛盾のない識別子を保つことへ削減されました 先ほどの患者の週間レポートで このデータのモデリングを見てみましょう その方法の1つは週間レポートを reportクラスとして表すものです reportクラスは 高レベルの同期識別子として識別されます その週以降 すべてのsixMinuteWalk TestDistanceサンプルのリストを含みます
各サンプルは同期識別子の メタデータキーを含むことがあります 高レベルのreport識別子から 導かれるものです
各サンプルは異なる週で 一意的に参照されることができます データはリモートサーバから患者のデバイスへ reportクラスモデルの形で同期できるので このリストからの個々のHKサンプルは HealthKitに保存できます
デモで見てみましょう “HealthKit入門”で作成したApp SmoothWalkerです デベロッパのウェブサイトで サンプルコードとしてダウンロードも可能です ここに週間レポートの ビューコントローラを作成します フェッチボタンを押して サーバから6分間歩行のサンプルを引き出し そこにビューコントローラを 追加したいと思います WeeklyReportTableViewControllerクラスを 見てみましょう フェッチボタンを選ぶと didTapFetchButtonメソッドが呼び出されます
ここでネットワークから サーバのレスポンスを引き出します そしてserverResponseと共に handleServerResponseメソッドを呼び出します handleServerResponseメソッドを実装 ではserverResponseから週間レポートを引き出し 該当するサンプルをHealthKitに保存します 初めにserverResponseから 週間レポートを引き出し
次に週間レポート内の 全サンプルをループします 週間レポートのサンプルをループして 各サンプルからHKQuantitySampleが返っています このループで まず個々の週間レポートに パラメータを設定します
メーター単位のquantityと serverHealthSampleからの値があります sampleTypeはsixMinuteWalkTestDistanceで 最後にstartDateとendDateがあります
そしてHKQuantitySampleを これらのパラメータで初期化します
sampleTypeとquantity startDateとendDateがあり そしてmetadataは 今はnilです ループから返されたサンプルは HealthKitに保存が必要です サンプルをHealthKitに保存 healthStoreを使って すべてのサンプルを保存しました completion handlerはビューコントローラに 新しいデータをロードします このコードを実行してみましょう
フェッチボタンを選択 週間レポートのサンプルと一緒に ビューコントローラが追加されます
もしフェッチボタンを再び選ぶと 重複したサンプルが 保存されているのが分かります これは誤りです HealthKitに重複したデータは要りません HKQuantitySampleにメタデータを含む時に どう変わるか見てみましょう メタデータの辞書を作り パラメータのリストに加えます serverHealthSampleから同期識別子を引き出し HKMetadataKeySyncIdentifierのキーに加えます 同様にserverHealthSampleから syncVersionを引き出し HKMetadataKeySyncVersionのキーに加えます そしてメタデータの辞書をHKQuantitySampleの パラメータのリストに追加します コードを再度実行して 見てみましょう
このデモでは HealthKit内の6分間歩行の全サンプルを 起動時に削除するコードを加えています しかしサンプルの削除には ユーザーの意図が確実に反映されるべきです
フェッチを選ぶと 週間レポートに 6分間歩行のサンプルが表示されます フェッチを何度か選択しても サンプルは二重になりません サンプルをHKMetadataSyncIdentifierと HKMetadataSyncVersionの両方に保存すれば サンプルの重複は起きないことが確認できました これでグラフを裏付けるデータが モデル化されました HealthKitへの外部データの同期は 想像よりも簡単です HealthKitは複数のデバイス間で データに矛盾がないよう保つのと同様に ヘルスエコシステム内の変更を 効率的にモニターできるツールを提供します 健康データの同期に 効率のよい方法をお話します ユーザーのデータを変更時は 必ず本人の意図の反映を確認します ユーザーが健康データの変更で 驚かないようにすべきです 効果的なクエリの実行方法を 考えてみてください クエリを組み合わせ 最小限のデータを 引き出して同期させるでしょう
健康データは 複数のデバイスにわたり存在するので デバイス間のデータに一貫性を保つよう 同期識別子とバージョン番号を使います Appleプラットフォームの ヘルスエコシステムの一部を紹介しましたが より多くのことができます 健康データを取り扱う際は セキュリティとプライバシーに配慮しましょう 外部のデータストアで 健康データを保持する場合は特に重要です Appleには多くの役立つリソースがあります 今日のデモのように美しいグラフの視覚化には CareKitフレームワークをご参照ください CareKitは 特に健康管理とケア提供に関する App開発用のオープンソースフレームワークです 最後にHealthKitには他にも 豊かな健康体験を生む多様な機能があります これらはワークアウトや病院の健康記録 頻繁に使われるデータタイプなど広範囲です このHealthKitのリソースで作られる すばらしいAppが待ち遠しいです 引き続きWWDCをお楽しみください
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。