Closed5

ExpoプロジェクトでHealthKitを扱う

YutoYuto

Expoドキュメントから検索した感じ、ライブラリはいくつかありそう

react-native-healthは前のリリースが1年前とかなのに対して、react-native-healthkitはメンテされてそうなのでまずはこっちを使ってみる。

Expo Goでは動かないそうで、自分のDev Clientが必要とのこと。developmentビルドを内部配信して確認する感じならまぁちょっと不便だが開発できなくはなさそう

YutoYuto

eas build --platform iosコマンドが「[ios.infoPlist]: withIosInfoPlistBaseMod: Cannot read properties of undefined (reading 'NSHealthShareUsageDescription')」というエラーで失敗した。
info.plistを設定すればいいのかなと思い、app.jsonのios.infoPlistNSHealthShareUsageDescriptionを渡すようにしても同じように失敗する。
↓これは失敗する

app.json
"ios": {
      "infoPlist": {
        "NSHealthShareUsageDescription": "体重データを使います。",
        "NSHealthUpdateUsageDescription": "体重データを更新します。"
      }
    },

app.jsonのpluginsでNSHealthShareUsageDescriptionを渡すように変えたらビルドできるようになった。

app.json
    "plugins": [
      [
        "@kingstinct/react-native-healthkit",
        {
          "NSHealthShareUsageDescription": "体重データを使います。",
          "NSHealthUpdateUsageDescription": "体重データを更新します。"
        }
      ]
    ],

説明文が短いとエラー

ビルドには成功したものの、info.plistの説明が短すぎてエラーになった。この説明文はデータアクセスの許可を求めるダイアルログに説明文として表示される。
多分12文字以下ならエラーになる。

YutoYuto

Expo Goでは動かないそうで、自分のDev Clientが必要とのこと。developmentビルドを内部配信して確認する感じならまぁちょっと不便だが開発できなくはなさそう

ここ勘違いしてた。expo-dev-clientライブラリは、Expo GoみたいなランチャーUIや、デバッグ用の通知などその他諸々をまとめてあるものライブラリで、これを導入して、

eas.json
{
  "build": {
    "development": {
      "developmentClient": true,
      ...
    }
}

とすることで、eas build --profile developmentのビルドがいわばExpo Goを内包したような開発用クライアントアプリになるっていうものだった。

なので、eas.jsonや他の設定ファイルの更新はビルドし直す必要があるようではあるが、ローカルの開発環境につながってリアルタイムにコードの更新がリフレッシュされる環境で開発でき、Expo Goと開発体験に大きな差はない。

YutoYuto

ライブラリの使い方

基本的に

  1. HealthKit.requestAuthorization()で権限リクエスト
  2. 実際に値を取得するget関数

という順番で処理をしないといけなくて、これにミスるとアプリがクラッシュする。
関数の引数が間違っていてもクラッシュする。など基本的にミスがあったらクラッシュするので開発はちょっとやりにくい。

1で権限をリクエストすると、許可しますか?モーダルが開く。

体重を取得

実際に体重を取得するコードはこんな感じ

await HealthKit.requestAuthorization([
  HKQuantityTypeIdentifier.bodyMass,
]); // 権限リクエスト 

const data = await HealthKit.getMostRecentQuantitySample(
  HKQuantityTypeIdentifier.bodyMass,
  "kg"
); // 取得

console.log(data); 
console.log
{
    "device": null,
    "endDate": 2024-08-09T17:01:08.000Z,
    "metadata": {},
    "quantity": 63.2,
    ...
}

という感じで取得できる。
ヘルスキットのドキュメントを見ながら、あとは型を追いながら何できるか見るしかないかなぁと思った。

YutoYuto

期間を指定して取得

HealthKit.queryQuantitiySamplesメソッドを使えば、過去好きな期間のデータも取得できる。

await HealthKit.queryQuantitySamples(
  HKQuantityTypeIdentifier.bodyMass,
  {
    from: new Date("2024-08-01"),
    unit: "kg",
  }
);

第2引数に取れるオプションは↓のような感じ

export type GenericQueryOptions = {
    readonly from?: Date;
    readonly to?: Date;
    readonly limit?: number;
    readonly ascending?: boolean;
    readonly anchor?: string;
};

これぐらいわかればやりたいことはできそう。

このスクラップは2024/09/02にクローズされました