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

This package is undergoing a new direction.
Please submit issues and pull request to terrillo/rn-apple-healthkit

とのことで、rn-apple-healthkitを使えばいいみたいです。

導入編

導入は4ステップです。

まずはライブラリを追加。

% npm install rn-apple-healthkit

次にリンク。

% react-native link rn-apple-healthkit

3番目にInfo.plitにパーミッション関係のメッセージを入れておきます。これがないとアプリが落ちるはずです。

<key>NSHealthShareUsageDescription</key>
<string>Read and understand health data.</string>
<key>NSHealthUpdateUsageDescription</key>
<string>Share workout data with other apps.</string>

最後に、iosディレクトリ以下のXcodeプロジェクト開いて、CapabilitiesからHealthKitをONにしましょう。READMEにも書いてあります。これがないと動きません。

利用編

権限のリクエスト

HealthKitへのアクセスをする前に、ユーザーに許可を求めるステップが必要です。ひとまずサンプル的に書くため、起動後に実行できるよう、React Nativeのルートコンポーネントと同じ場所に書いておきました。

import AppleHealthKit from 'rn-apple-healthkit';
const PERMS = AppleHealthKit.Constants.Permissions;

const options = {
  permissions: {
    read: [PERMS.StepCount, PERMS.Weight, PERMS.SleepAnalysis],
  },
};

AppleHealthKit.initHealthKit(options, (err, results) => {
  if (err) {
    console.log('error initializing Healthkit: ', err);
  } else {
    console.log(results);
  }
});

データの取得

体重

例えば体重ならこんな感じでgetWeightSamplesにオプションを渡すと指定した期間のデータが返ってきます。

import AppleHealthKit from 'rn-apple-healthkit';
const UNITS = AppleHealthKit.Constants.Units;

const options = {
  unit: UNITS.gram,
  startDate: new Date(2018, 4, 1).toISOString(), // 5月1日以降
};
AppleHealthKit.getWeightSamples(options, (err, results) => {
  if (err) {
    console.log(err);
  } else {
    console.log(results);
  }
});

余談ですが、JavascriptのDateはmonthの範囲が0~11であることをすっかり忘れていて、最初次のように書いていてデータが取れずしばらくハマリました。

new Date(2018, 5, 1) // これだと2018年6月1日になる

getWeightSamplesのコードのresultsにはこんな感じでオブジェクトが入ってきます。(Hugoの処理のせいか、変な{1}っていうのが入るのはなんだろう…?あとで直します)

[
  {
    startDate: "2018-05-08T07:09:51.974+0900",
    endDate: "2018-05-08T07:09:51.974+0900",
    value: 58799.9992370605
  }
]

単位指定しないとポンドで来ちゃうからgramに変更してます。

睡眠

睡眠はほぼ同じような感じで取れました。

const options = {
  startDate: new Date(2018, 4, 1).toISOString(),
};
AppleHealthKit.getSleepSamples(options, (err, results) => {
  if (err) {
    console.log(err);
  } else {
    console.log(results);
  }
});

resultsにはこんな具合で、INBETとかASLEEPといったステータスとその時間が返ってきました。

[
  {
	  startDate: "2018-05-07T01:14:00.000+0900",
	  endDate: "2018-05-07T07:14:00.000+0900",
	  value: "INBED"
  },
  {
	  startDate: "2018-05-07T06:57:00.000+0900",
	  endDate: "2018-05-07T07:14:00.000+0900",
	  value: "ASLEEP"
  }
]

ヘルスケアアプリで見ると

  • INBED は就寝
  • ASLEEP は睡眠

となっているようで、眠っているときと寝ようとしているときとでステータスを分けられるようです。

サンプルアプリ

動くと思われるアプリをGitHubに置いておきました。

pi-chan/RNHealthKitSample
rn-apple-healthkit sample app. Contribute to pi-chan/RNHealthKitSample development by creating an account on GitHub.