React Nativeでヘルスケアに入っているデータを読み出せるかということを調査したので軽くまとめます。幸い睡眠や体重を記録しているのでそのデータを使って試してみました。

React Nativeのライブラリとしてはこちらを利用しました。

terrillo/rn-apple-healthkit: A React Native package for interacting with Apple HealthKit

↓というのもあったのですが、

GregWilson/react-native-apple-healthkit: A React Native bridge module for interacting with Apple HealthKit data

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に置いておきました。