WWDC Quick Look 💓 By SwiftGGTeam
Synchronize health data with HealthKit

Synchronize health data with HealthKit

元の動画を見る

ハイライト

HealthKit は、HKAnchoredObjectQuery を使用して追加と削除を監視し、HKMetadataKeySyncIdentifier と HKMetadataKeySyncVersion を使用して、複数のデバイスにわたって外部サーバーによって書き戻されたヘルス サンプルを重複排除および更新します。

主要内容

このセッションは回復アプリから始まります。患者は iPhone と Apple Watch を使用して毎日の歩数を記録し、理学療法士は毎週 6 分間の歩行テストの結果を記録します。患者は傾向を気にし、セラピストは同じデータを確認する必要があり、アプリはグラフをサーバーに同期する必要があります。

それだけに頼るならHKStatisticsCollectionQueryスケジュールされた更新では、アプリは起動時または数時間ごとに 1 週​​間全体の歩数を再計算する必要があります。健康データが変更されていない場合、計算は 2 倍になります。新しい歩数が 1 日分しかない場合でも、1 週間全体の結果がサーバーに送信される可能性があります。健康データが古ければ古いほど、無駄がより明らかになります。

Apple が提供するアプローチは、クエリを 2 つのレイヤーに分割することです。HKAnchoredObjectQueryどのサンプルが追加または削除されるかを App HealthKit に伝える責任を負います。HKStatisticsCollectionQuery影響を受ける日付の統計のみが再計算されます。サーバーが取得するのは、履歴データのバッチ全体ではなく、変更された毎日の統計です。

逆方向の同期はより敏感です。セラピストのサーバーからの 6 分間の歩行テストが患者の HealthKit に保存されます。同じ週次レポートが iPhone に送信され、HealthKit 経由で Apple Watch に同期される可能性があります。アプリはユーザーの健康データを自由に書き換えたり削除したりすることはできません。HKMetadataKeySyncIdentifierそしてHKMetadataKeySyncVersionバージョンの決定は HealthKit に任せてください。

詳細

統計クエリのみを使用すると、ネットワークと計算が無駄になります

(02:56) ステップ チャートが最初に思い浮かぶはずです。HKStatisticsCollectionQuery。日ごとの歩数を集計するのに適しており、回復傾向グラフの作成にも適しています。問題は同期シナリオにあります。アプリが固定頻度で統計クエリを再実行する場合、HealthKit でどの日が変更されたのかがわかりません。

旧流程
1. HKStatisticsCollectionQuery 计算一周步数图表
2. App 启动或定时再次执行查询
3. 每次把整周统计结果发送到服务器

改造目标
1. 先找出 HealthKit 中发生变化的样本
2. 只重算这些样本影响到的日期
3. 只把更新后的日期结果发送到外部数据存储

キーポイント:

  • HKStatisticsCollectionQueryグラフの生成を担当しますが、データが変更されたかどうかを判断する責任はありません。
  • 固定頻度のリフレッシュでは計算が繰り返され、変更されていないデータが繰り返しサーバーに送信されます。
  • 外部データ ストアは、リモート サーバー、ローカル Core Data、または SQLite にすることができます。

アンカーを使用すると、アプリは変更セットのみを取得できます

04:32HKAnchoredObjectQuery核心はアンカーです。初めてクエリを実行するとき、アンカーはnil, HealthKit は、現在一致しているすべてのサンプルを返し、ハンドラーに新しいアンカーを与えます。次のクエリは保存されたアンカーを渡し、HealthKit はこの後に追加および削除されたサンプルのみを返します。

第一次查询
anchor = nil
HealthKit 当前样本 = A, B, C
handler 收到 = A, B, C
保存 newAnchor

后续查询
HealthKit 新增 = D, E
HealthKit 删除 = B
使用 persistedAnchor 再次查询
handler 收到 = D, E, deleted B
再次保存 newAnchor

キーポイント:

  • アンカーは、HealthKit データベースが特定の時点まで進化した位置を表します。
  • ハンドラーは新しいサンプルと削除サンプルを受け取ります。
  • アンカーを保存した後、アプリは A や C などの変更されていない古いサンプルを毎回スキャンする必要がありません。

2 つのクエリの連携: 最初に変更を特定し、次に統計を再計算します。

(07:18) この講演では公式のコード スニペットは提供されていませんが、トランスクリプトには実装シーケンスが示されています。アンカーされたクエリはステップ サンプル タイプと永続アンカーを使用します。ハンドラーは、返されたサンプルの日付に基づいて述語を作成します。次に、この述語を使用して統計クエリ コレクションを作成し、日ごとの累積ステップ数を計算します。

HKAnchoredObjectQuery
sampleType = step count
predicate = nil
anchor = persistedAnchor
initialResultsHandler = handler
updateHandler = handler

handler
1. 读取 HealthKit 返回的 samples
2. 从 samples 的日期生成 predicate
3. 保存 HealthKit 返回的新 anchor
4. 调用 fetchStatistics(predicate)

fetchStatistics(predicate)
1. anchorDate = Monday midnight
2. interval = one day
3. sampleType = step count
4. options = cumulativeSum
5. HKStatisticsCollectionQuery 使用上一步 predicate

キーポイント:

  • initialResultsHandlerそしてupdateHandlerどちらのマップ変更も統計の更新に反映されるため、同じ処理ブロックを再利用できます。
  • 述語はアンカー クエリによって返されたサンプルの日付範囲から取得され、統計クエリの計算範囲を制限するために使用されます。 -cumulativeSum「1 日あたりの総歩数」というグラフの目標に対応します。
  • クエリを実行するためのエントリ ポイントはまだhealthStore

6 分間の歩行テストはサンプルとして保存する必要があります

(10:24) 2020 年に、HealthKit には次のような新しいモビリティ データ タイプのセットが追加されました。sixMinuteWalkTestDistance。歩数は日ごとにまとめるのに適しています。 6 分間の歩行テストの頻度は比較的低いです。患者とセラピストは各テストの結果を確認する必要がある場合があるため、週次レポートの各テストを個別のサンプルとしてここに保存する必要があります。

服务器周报
1. 读取 weekly report
2. 遍历 weekly report 中的每条 serverHealthSample
3. 创建 HKQuantitySample
   - quantity 使用 meter 单位
   - value 来自 serverHealthSample
   - sampleType = sixMinuteWalkTestDistance
   - startDate / endDate 来自测试记录
4. healthStore 保存这些 samples

キーポイント:

  • 同じアプリ内で、異なる HealthKit データ型は異なる同期戦略を使用できます。
  • ステップ数はサンプル サイズが大きく、共通の目標はチャート統計です。
  • 6分間の歩行テストはサンプルサイズが小さく、単一の記録自体が診断上および治療上重要です。
  • サンプルを削除する前に、まずクエリを実行して、それが自分のアプリによって書かれたものであることを確認する必要があり、削除はユーザーの意図に従う必要があります。

同期識別子とバージョンは重複排除と更新を担当します

(13:54) 外部サーバーがテスト記録を更新する場合、アプリはそれを単純に再保存することはできません。 HealthKit は 2 つのメタデータ キーを提供します。HKMetadataKeySyncIdentifierこれは、健全な生態系における同じサンプルを識別するために使用される文字列です。HKMetadataKeySyncVersionサンプルが更新されたかどうかを判断するために使用される番号です。

保存服务器样本
metadata[HKMetadataKeySyncIdentifier] = serverHealthSample.syncIdentifier
metadata[HKMetadataKeySyncVersion] = serverHealthSample.syncVersion
HKQuantitySample 使用这份 metadata
healthStore 保存 sample

HealthKit 行为
同一 syncIdentifier + 同一 version 再次写入 -> 忽略重复样本
同一 syncIdentifier + 更高 version 写入 -> 用新样本覆盖旧样本
基于 sync identifier 的操作 -> 保持事务安全

キーポイント:

  • 識別子は外部データ ソースからの安定したサンプル識別子である必要があり、毎回新しい値を生成することはできません。
  • バージョンが上がると、HealthKit はそれを同じサンプルの更新として扱います。
  • 同じ週次レポートが iPhone に同期され、次に Apple Watch に同期されると、HealthKit は重複書き込みを識別します。
  • アプリが識別子とバージョンを維持している限り、競合解決とマルチデバイスの一貫性は HealthKit によって処理されます。

重要ポイント

  • リハビリテーション週間レポートの同期: 手順: 6 分間歩行テストの週間レポートをセラピスト サーバーから患者のアプリに同期します。実行する価値がある理由: セッションの明示的な使用sixMinuteWalkTestDistanceこのテストをモデル化します。開始方法: サーバー サンプルを次の場所にマッピングします。HKQuantitySample、使用HKMetadataKeySyncIdentifierそしてHKMetadataKeySyncVersionメタデータを書き込みます。
  • 歩数傾向の共有: 行うべきこと: 患者が承認した後、毎日の合計歩数の傾向を看護チームと同期します。実行する価値がある理由:HKAnchoredObjectQuery毎回 1 週間分のデータをアップロードする必要がないように、変更サンプルのみを監視できます。開始方法: まずアンカー クエリを使用して変更日を検索し、次に使用します。HKStatisticsCollectionQueryこれらの日付を計算しますcumulativeSum
  • ローカル キャッシュ調整: 対処方法: HealthKit データ用のコア データ キャッシュまたは SQLite キャッシュを作成し、ヘルス データが変更された場合にのみキャッシュを更新します。実行する価値がある理由: トランスクリプトは外部データ ストレージをネイティブ データベースに拡張します。開始方法: HealthKit アンカーを永続化し、ハンドラーによって返された新規および削除されたサンプルをキャッシュされた追加、削除、および変更に変換します。
  • 重複輸入保護: 対処方法: 病院、コーチ、またはサードパーティ製デバイスからの健康サンプルに対する安定した外部 ID。実行する価値がある理由: 同じレコードが iPhone と Apple Watch から HealthKit に複数回入力される可能性があります。開始方法: サーバーレコード ID を書き込みます。HKMetadataKeySyncIdentifierにサーバーのバージョン番号を書き込みますHKMetadataKeySyncVersion

関連セッション

  • HealthKit 入門 - この同期レクチャーでは、SmoothWalker の例を直接使用しており、前提条件となるコンテンツでは HealthKit の認証、読み取りと書き込み、および基本的なクエリについて説明します。
  • 歩数計測を超えて — 歩数計測や 6 分間の歩行テスト後の読み取りに適したモビリティ指標の拡張を継続します。
  • HealthKit の新機能 — ECG、症状ログ、モビリティ データ タイプなど、2020 年の HealthKit の新しい機能の概要。
  • CareKit の新機能 - セッションの最後では、ケア シナリオで図やタスク エクスペリエンスを構築するために使用される CareKit について推奨します。

コメント

GitHub Issues · utterances