ExpoプロジェクトでHealthKitを扱う
Expoドキュメントから検索した感じ、ライブラリはいくつかありそう
react-native-healthは前のリリースが1年前とかなのに対して、react-native-healthkitはメンテされてそうなのでまずはこっちを使ってみる。
Expo Goでは動かないそうで、自分のDev Clientが必要とのこと。developmentビルドを内部配信して確認する感じならまぁちょっと不便だが開発できなくはなさそう
eas build --platform ios
コマンドが「[ios.infoPlist]: withIosInfoPlistBaseMod: Cannot read properties of undefined (reading 'NSHealthShareUsageDescription')」というエラーで失敗した。
info.plist
を設定すればいいのかなと思い、app.jsonのios.infoPlist
にNSHealthShareUsageDescription
を渡すようにしても同じように失敗する。
↓これは失敗する
"ios": {
"infoPlist": {
"NSHealthShareUsageDescription": "体重データを使います。",
"NSHealthUpdateUsageDescription": "体重データを更新します。"
}
},
app.json
のpluginsでNSHealthShareUsageDescription
を渡すように変えたらビルドできるようになった。
"plugins": [
[
"@kingstinct/react-native-healthkit",
{
"NSHealthShareUsageDescription": "体重データを使います。",
"NSHealthUpdateUsageDescription": "体重データを更新します。"
}
]
],
説明文が短いとエラー
ビルドには成功したものの、info.plist
の説明が短すぎてエラーになった。この説明文はデータアクセスの許可を求めるダイアルログに説明文として表示される。
多分12文字以下ならエラーになる。
Expo Goでは動かないそうで、自分のDev Clientが必要とのこと。developmentビルドを内部配信して確認する感じならまぁちょっと不便だが開発できなくはなさそう
ここ勘違いしてた。expo-dev-clientライブラリは、Expo GoみたいなランチャーUIや、デバッグ用の通知などその他諸々をまとめてあるものライブラリで、これを導入して、
{
"build": {
"development": {
"developmentClient": true,
...
}
}
とすることで、eas build --profile development
のビルドがいわばExpo Goを内包したような開発用クライアントアプリになるっていうものだった。
なので、eas.jsonや他の設定ファイルの更新はビルドし直す必要があるようではあるが、ローカルの開発環境につながってリアルタイムにコードの更新がリフレッシュされる環境で開発でき、Expo Goと開発体験に大きな差はない。
ライブラリの使い方
基本的に
-
HealthKit.requestAuthorization()
で権限リクエスト - 実際に値を取得するget関数
という順番で処理をしないといけなくて、これにミスるとアプリがクラッシュする。
関数の引数が間違っていてもクラッシュする。など基本的にミスがあったらクラッシュするので開発はちょっとやりにくい。
1で権限をリクエストすると、許可しますか?モーダルが開く。
体重を取得
実際に体重を取得するコードはこんな感じ
await HealthKit.requestAuthorization([
HKQuantityTypeIdentifier.bodyMass,
]); // 権限リクエスト
const data = await HealthKit.getMostRecentQuantitySample(
HKQuantityTypeIdentifier.bodyMass,
"kg"
); // 取得
console.log(data);
{
"device": null,
"endDate": 2024-08-09T17:01:08.000Z,
"metadata": {},
"quantity": 63.2,
...
}
という感じで取得できる。
ヘルスキットのドキュメントを見ながら、あとは型を追いながら何できるか見るしかないかなぁと思った。
期間を指定して取得
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;
};
これぐらいわかればやりたいことはできそう。