React Nativeでヘルスケアに入っているデータを読み出せるかということを調査したので軽くまとめます。幸い睡眠や体重を記録しているのでそのデータを使って試してみました。
React Nativeのライブラリとしてはこちらを利用しました。
terrillo/rn-apple-healthkit: A React Native package for interacting with Apple HealthKit
↓というのもあったのですが、
1This package is undergoing a new direction.
2Please submit issues and pull request to terrillo/rn-apple-healthkit
とのことで、rn-apple-healthkitを使えばいいみたいです。
導入編
導入は4ステップです。
まずはライブラリを追加。
1% npm install rn-apple-healthkit
次にリンク。
1% react-native link rn-apple-healthkit
3番目にInfo.plitにパーミッション関係のメッセージを入れておきます。これがないとアプリが落ちるはずです。
1<key>NSHealthShareUsageDescription</key>
2<string>Read and understand health data.</string>
3<key>NSHealthUpdateUsageDescription</key>
4<string>Share workout data with other apps.</string>
最後に、iosディレクトリ以下のXcodeプロジェクト開いて、CapabilitiesからHealthKitをONにしましょう。READMEにも書いてあります。これがないと動きません。
利用編
権限のリクエスト
HealthKitへのアクセスをする前に、ユーザーに許可を求めるステップが必要です。ひとまずサンプル的に書くため、起動後に実行できるよう、React Nativeのルートコンポーネントと同じ場所に書いておきました。
1import AppleHealthKit from 'rn-apple-healthkit';
2const PERMS = AppleHealthKit.Constants.Permissions;
3
4const options = {
5 permissions: {
6 read: [PERMS.StepCount, PERMS.Weight, PERMS.SleepAnalysis],
7 },
8};
9
10AppleHealthKit.initHealthKit(options, (err, results) => {
11 if (err) {
12 console.log('error initializing Healthkit: ', err);
13 } else {
14 console.log(results);
15 }
16});
データの取得
体重
例えば体重ならこんな感じでgetWeightSamplesにオプションを渡すと指定した期間のデータが返ってきます。
1import AppleHealthKit from 'rn-apple-healthkit';
2const UNITS = AppleHealthKit.Constants.Units;
3
4const options = {
5 unit: UNITS.gram,
6 startDate: new Date(2018, 4, 1).toISOString(), // 5月1日以降
7};
8AppleHealthKit.getWeightSamples(options, (err, results) => {
9 if (err) {
10 console.log(err);
11 } else {
12 console.log(results);
13 }
14});
余談ですが、JavascriptのDateはmonthの範囲が0~11であることをすっかり忘れていて、最初次のように書いていてデータが取れずしばらくハマリました。
1new Date(2018, 5, 1) // これだと2018年6月1日になる
getWeightSamplesのコードのresultsにはこんな感じでオブジェクトが入ってきます。(Hugoの処理のせいか、変な{1}っていうのが入るのはなんだろう…?あとで直します)
1[
2 {
3 startDate: "2018-05-08T07:09:51.974+0900",
4 endDate: "2018-05-08T07:09:51.974+0900",
5 value: 58799.9992370605
6 }
7]
単位指定しないとポンドで来ちゃうからgramに変更してます。
睡眠
睡眠はほぼ同じような感じで取れました。
1const options = {
2 startDate: new Date(2018, 4, 1).toISOString(),
3};
4AppleHealthKit.getSleepSamples(options, (err, results) => {
5 if (err) {
6 console.log(err);
7 } else {
8 console.log(results);
9 }
10});
resultsにはこんな具合で、INBETとかASLEEPといったステータスとその時間が返ってきました。
1[
2 {
3 startDate: "2018-05-07T01:14:00.000+0900",
4 endDate: "2018-05-07T07:14:00.000+0900",
5 value: "INBED"
6 },
7 {
8 startDate: "2018-05-07T06:57:00.000+0900",
9 endDate: "2018-05-07T07:14:00.000+0900",
10 value: "ASLEEP"
11 }
12]
ヘルスケアアプリで見ると
- INBED は就寝
- ASLEEP は睡眠
となっているようで、眠っているときと寝ようとしているときとでステータスを分けられるようです。
サンプルアプリ
動くと思われるアプリをGitHubに置いておきました。