Apple HealthKitをReact Nativeで同期する方法:開発者ガイド
React NativeアプリにApple HealthKitを統合する方法を学びましょう。このステップバイステップのガイドでは、Xcodeの設定、パーミッション、カスタムフックを使用した歩数やワークアウトなどの健康データの読み取りと書き込みをカバーします。
このページの内容
ヘルス&フィットネス技術の隆盛する世界において、ユーザーはお気に入りのアプリとApple Healthの中央ダッシュボード間のシームレスな連携を期待しています。React Native開発者にとって、この豊富でユーザー許可を得たデータにアクセスすることは大変そうに聞こえるかもしれません。それは多くの場合、ネイティブiOS設定のナビゲート、機微な権限の処理、そして全く異なるエコシステムの理解を伴います。
この記事は、そのプロセスを明確にします。AppleのHealthKitをReact Nativeアプリケーションに連携するための実践的なステップバイステップガイドを作成します。歩数、睡眠分析、ワークアウトデータなどの基本的な健康メトリクスを読み書きするために、一般的なreact-native-healthライブラリを使用します。コードをよりクリーンで再利用しやすく、管理しやすいものにするために、すべてのHealthKit連携をカスタムReactフックに包みます。
前提条件:
- XcodeがインストールされたmacOSコンピュータ。
- 物理的なiOSデバイス(HealthKit機能はシミュレーターでは制限されています)。
- Node.js(LTSバージョン)およびReact Native開発環境。
- React NativeとTypeScriptの基本知識。
開発者にとってなぜ重要か:Apple Healthとの連携は、より全体的かつパーソナライズされた体験を提供することで、ユーザーエンゲージメントを大幅に向上させることができます。あなたのアプリがユーザーの包括的な健康データに貢献し、その恩恵を受けることを可能にし、より価値があり競争力のあるものにします。
問題の理解
Apple HealthKitは強力ですが、保護されたフレームワークです。これはユーザーの健康とフィットネスのデータの中央リポジトリとして機能します。。明示的できめ細やかなユーザー許可なしには、アプリはこのデータにアクセスできません。React Native開発者にとって主な課題は次のとおりです:
- ネイティブ設定:HealthKitはiOSネイティブのフレームワークです。通常のJavaScript環境とは異なる、Xcodeでの特定の設定が必要です。
- 権限管理:Appleは厳格なプライバシーモデルを持っています。ユーザーが一度でも権限を拒否すると、再びプロンプトは表示されません。ユーザーは設定アプリで手動で有効にする必要があり、あなたのアプリはこのようなフローを処理する必要があります。
- データ同期:データの読み書きには、さまざまなデータ型、単位、非同期操作の理解が必要です。
- UI/UX:ユーザーインターフェースは、これらの権限が必要な理由を明確に説明し、アクセスが拒否されたケースを適切に処理する必要があります。
私たちのアプローチは、ライブラリを使用してネイティブの複雑さを抽象化し、カスタムフックを使用してReact Nativeコンポーネント用のクリーンで再利用可能なインターフェースを作成することで、これらの課題に直接取り組むことです。
前提条件
コーディングを開始する前に、プロジェクトをセットアップしましょう。
-
新しいReact Nativeプロジェクトを作成(TypeScriptを使用):
bash npx create-react-native-app MyHealthApp --template react-native-template-typescript cd MyHealthApp -
HealthKitライブラリをインストール:
react-native-healthを使用します。これはHealthKit連携に広く使われているライブラリです。bash npm install react-native-health -
iOS依存関係をインストール:
bash cd ios && pod install
ステップ1:ネイティブiOS設定 ✨
これは最も重要なステップです。これを間違うと、他に何も機能しません。
何をしているか
Xcodeに、我们的アプリがHealthKitフレームワークを使用することと、ユーザーの健康データへのアクセスが必要な理由を説明するメッセージを提供することを伝える必要があります。
実装
-
Xcodeプロジェクトを開く:Xcodeで
ios/MyHealthApp.xcworkspaceファイルを開きます。 -
HealthKit Capabilityを追加:
- 左側のナビゲーターでプロジェクト」を選択します。
- 「Signing & Capabilities」タブに移動します。
- 「+ Capability」をクリックします。
- 「HealthKit」を検索してダブルクリックして追加します。これにより、iOSはあなたのアプリがHealthKitフレームワークを使用するつもりがであることを認識します。
-
権限のために
Info.plistを設定:- Xcodeで、
Info.plistファイルを見つけて開きます。 - 「+」ボタンをクリックして2つの新しいキーを追加します:
- Privacy - Health Share Usage Description:データを読み取るための許可をリクエストるときに表示されるメッセージです。
- Privacy - Health Update Usage Description:データを書き込むための許可をリクエストするときに表示されるメッセージです。
- それぞれにユーザー友好的な文字列値を提供します、例:
- Share Usageの値:
当アプリでは、パーソナライズされた洞察の提供と進捗の追跡のために健康データを使用します。 - Update Usageの値:
当アプリでは、ワークアウトとアクティビティデータをApple Healthに保存する必要があります。
- Share Usageの値:
Info.plistのソースコードは次のようになります:xml <key>NSHealthShareUsageDescription</key> <string>当アプリでは、パーソナライズされた洞察の提供と進捗の追跡のために健康データを使用します。</string> <key>NSHealthUpdateUsageDescription</key> <string>当アプリでは、ワークアウトとアクティビティデータをApple Healthに保存する必要があります。</string> - Xcodeで、
動作の仕組み
HealthKit capabilityを追加すると、必要なネイティブフレームワークがプロジェクトにリンクされます。Info.plistエントリはAppleからの必須のセキュリティ機能です。iOSは自動的にこれらのメッセージを権限同意画面に表示するため、明確でユーザーの信頼を構築することが重要です。
ステップ2:カスタムuseHealthDataフックの作成
コンポーネントコードをクリーンに保つために、useHealthData.tsというカスタムフックを作成します。このフックは権限管理与えとreact-native-healthライブラリとのすべての連携を管理します。
何をしているか
アプリが必要とする特定の読み取りと書き込みの権限を定義し、HealthKitを初期化する関数を作成します。
実装
-
フックファイルを作成:プロジェクトの
srcディレクトリに新しいフォルダhooksを作成し、その中にuseHealthData.tsというファイルを作成します。 -
初期フック構造を設定:
typescript // src/hooks/useHealthData.ts import AppleHealthKit, { HealthKitPermissions, } from 'react-native-health'; import { useEffect, useState } from 'react'; /* リクエストする権限を定義 */ const permissions: HealthKitPermissions = { permissions: { read: [ AppleHealthKit.Constants.Permissions.Steps, AppleHealthKit.Constants.Permissions.SleepAnalysis, AppleHealthKit.Constants.Permissions.Workout, ], write: [ AppleHealthKit.Constants.Permissions.Steps, AppleHealthKit.Constants.Permissions.SleepAnalysis, AppleHealthKit.Constants.Permissions.Workout, ], }, }; const useHealthData = () => { const [hasPermissions, setHasPermissions] = useState(false); useEffect(() => { // HealthKitを初期化 AppleHealthKit.initHealthKit(permissions, (error: string) => { if (error) { console.log('[ERROR] Cannot grant permissions!'); return; } setHasPermissions(true); }); }, []); // データを読み書きする関数をここに追加 return { hasPermissions, }; }; export default useHealthData;
動作の仕組み
ライブラリからAppleHealthKitとHealthKitPermissionsをインポートします。次に、読み取りと書き込みたいデータ型を正確に指定するpermissionsオブジェクトを定義します。useEffectフックはAppleHealthKit.initHealthKitを呼び出し、初めて呼び出されたときにネイティブiOS権限プロンプトをトリガーします。ユーザーが権限を付与すると、hasPermissions状態がtrueに設定されます。
ステップ3:健康データの読み取り(歩数、睡眠、ワークアウト)
次に、フックを拡張してデータを読み取りましょう。
何をしているか
ユーザーの過去7日間の歩数、睡眠データ、ワークアウト履歴を取得するために、useHealthDataフックに関数を追加します。
実装
// useHealthDataフック内のreturnステートメントの前に以下を追加
const [steps, setSteps] = useState(0);
const [sleep, setSleep] = useState<any[]>([]); // 例示用に簡略化
const [workouts, setWorkouts] = useState<any[]>([]); // 例示用に簡略化
useEffect(() => {
if (!hasPermissions) {
return;
}
const options = {
startDate: new Date(new Date().setDate(new Date().getDate() - 7)).toISOString(), // 過去7日間
endDate: new Date().toISOString(),
};
// 歩数を取得
AppleHealthKit.getStepCount(options, (err, results) => {
if (err) {
console.log('Error getting step count:', err);
return;
}
setSteps(results.value);
});
// 睡眠分析を取得
AppleHealthKit.getSleepSamples(options, (err, results) => {
if (err) {
console.log('Error getting sleep samples:', err);
return;
}
setSleep(results);
});
// ワークアウトを取得
AppleHealthKit.getSamples({ ...options, type: 'Workout' }, (err, results) => {
if (err) {
console.log('Error getting workout samples:', err);
return;
}
setWorkouts(results);
});
}, [hasPermissions]);
// returnステートメントを更新
return {
hasPermissions,
steps,
sleep,
workouts,
};
動作の仕組み
hasPermissionsがtrueになるたびに実行される2番目のuseEffectを使用します。その中で、過去1週間分のデータをクエリするための日付オプションを定義します。次に、getStepCountやgetSleepSamplesなどのreact-native-healthが提供する特定のメソッドを呼び出します。各関数は日付オプションとコールバックを取り、コールバックはエラーまたはリクエストされたデータを返します。
ステップ4:健康データの書き込み(ワークアウトの保存)
データの読み取りは便利ですが、多くのアプリはHealthKitにデータを貢献する必要もあります。
何をしているか
Apple Healthに新しいワークアウトを保存できるフックに機能を追加します。
実装
// useHealthDataフック内にこの関数を追加
const saveWorkout = () => {
if (!hasPermissions) {
console.log('Cannot save workout without permissions.');
return;
}
const options = {
type: AppleHealthKit.Constants.Workouts.Running,
startDate: new Date(new Date().getTime() - 60 * 60 * 1000).toISOString(), // 1時間前
endDate: new Date().toISOString(),
energyBurned: 350, // カロリー単位
totalDistance: 5, // キロメートル単位
};
AppleHealthKit.saveWorkout(options, (err, results) => {
if (err) {
console.log('Error saving workout:', err);
return;
}
console.log('Workout saved successfully:', results);
// ここでワークアウトを再取得してUIを更新したい場合があります
});
};
// returnステートメントを更新
return {
hasPermissions,
steps,
sleep,
workouts,
saveWorkout, // 新しい関数を公開
};
動作の仕組み
saveWorkout関数は、ワークアウトタイプ、開始時間と終了時間、消費カロリーや距離などの主要指標の詳細を含むoptionsオブジェクトを構築します。次に、AppleHealthKit.saveWorkoutを呼び出します。成功すると、新しいワークアウトはすぐにユーザーのApple Healthアプリに表示されます。
すべてを組み合わせる
これで、強力なuseHealthDataフックを任意のコンポーネントで非常にクリーンなコードで使用できます。
完全なuseHealthData.tsフック
// src/hooks/useHealthData.ts
import AppleHealthKit, {
HealthKitPermissions,
HealthValue,
SleepSample,
WorkoutSample,
} from 'react-native-health';
import { useEffect, useState } from 'react';
const permissions: HealthKitPermissions = {
permissions: {
read: [
AppleHealthKit.Constants.Permissions.Steps,
AppleHealthKit.Constants.Permissions.SleepAnalysis,
AppleHealthKit.Constants.Permissions.Workout,
],
write: [
AppleHealthKit.Constants.Permissions.Steps,
AppleHealthKit.Constants.Permissions.SleepAnalysis,
AppleHealthKit.Constants.Permissions.Workout,
],
},
};
const useHealthData = () => {
const [hasPermissions, setHasPermissions] = useState(false);
const [steps, setSteps] = useState(0);
const [sleep, setSleep] = useState<SleepSample[]>([]);
const [workouts, setWorkouts] = useState<WorkoutSample[]>([]);
useEffect(() => {
AppleHealthKit.initHealthKit(permissions, (error: string) => {
if (error) {
console.log('[ERROR] Cannot grant permissions!');
return;
}
setHasPermissions(true);
});
}, []);
useEffect(() => {
if (!hasPermissions) {
return;
}
const options = {
startDate: new Date(new Date().setDate(new Date().getDate() - 7)).toISOString(),
endDate: new Date().toISOString(),
};
AppleHealthKit.getStepCount(options, (err, results: HealthValue) => {
if (err) {
console.log('Error getting step count:', err);
return;
}
setSteps(results.value);
});
AppleHealthKit.getSleepSamples(options, (err, results: SleepSample[]) => {
if (err) {
console.log('Error getting sleep samples:', err);
return;
}
setSleep(results);
});
AppleHealthKit.getAnchoredWorkouts(options, (err, results: WorkoutSample[]) => {
if (err) {
console.log('Error getting workout samples:', err);
return;
}
setWorkouts(results);
});
}, [hasPermissions]);
const saveWorkout = () => {
if (!hasPermissions) {
console.log('Cannot save workout without permissions.');
return;
}
const options = {
type: AppleHealthKit.Constants.Workouts.Running,
startDate: new Date(new Date().getTime() - 60 * 60 * 1000).toISOString(),
endDate: new Date().toISOString(),
energyBurned: 350,
totalDistance: 5,
};
AppleHealthKit.saveWorkout(options, (err, results) => {
if (err) {
console.log('Error saving workout:', err);
return;
}
console.log('Workout saved successfully:', results);
});
};
return {
hasPermissions,
steps,
sleep,
workouts,
saveWorkout,
};
};
export default useHealthData;
例のApp.tsxコンポーネント
// App.tsx
import React from 'react';
import {
SafeAreaView,
ScrollView,
StatusBar,
StyleSheet,
Text,
useColorScheme,
View,
Button,
} from 'react-native';
import { Colors } from 'react-native/Libraries/NewAppScreen';
import useHealthData from './src/hooks/useHealthData';
const App = () => {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
const { steps, sleep, workouts, saveWorkout } = useHealthData();
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
<ScrollView contentInsetAdjustmentBehavior="automatic" style={backgroundStyle}>
<View style={styles.container}>
<Text style={styles.title}>HealthKit デモ</Text>
<View style={styles.metricBox}>
<Text style={styles.metricValue}>{steps.toLocaleString()}</Text>
<Text style={styles.metricLabel}>歩数(過去7日間)</Text>
</View>
<View style={styles.metricBox}>
<Text style={styles.metricValue}>{sleep.length}</Text>
<Text style={styles.metricLabel}>睡眠記録(過去7日間)</Text>
</View>
<View style={styles.metricBox}>
<Text style={styles.metricValue}>{workouts.length}</Text>
<Text style={styles.metricLabel}>ワークアウト(過去7日間)</Text>
</View>
<Button title="テストワークアウトを保存" onPress={saveWorkout} />
</View>
</ScrollView>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: { padding: 20 },
title: { fontSize: 24, fontWeight: 'bold', marginBottom: 20 },
metricBox: {
marginBottom: 15,
padding: 15,
borderRadius: 10,
backgroundColor: '#f0f0f0',
},
metricValue: { fontSize: 20, fontWeight: '600' },
metricLabel: { fontSize: 14, color: '#555', marginTop: 5 },
});
export default App;
セキュリティのベストプラクティス
- 必要なものだけをリクエストする:使用しないデータの権限をリクエストしないでください。これはユーザーに不信感を与え、アクセス全体を拒否する原因となる可能性があります。
- 理由を説明する:
Info.plistの説明を使用して、アプリが健康データが必要な理由を明確かつ正直に説明してください。 - 拒否された権限を処理する:ユーザーが権限を拒否した場合でも、アプリはまだ適切に機能する必要があります。ユーザーが手動で権限を有効にできる設定アプリに導くボタンまたはガイドを提供してください。アプリから再プロンプトを出すことはできないことを忘れないでください。
結論
Apple HealthKitをReact Nativeアプリと連携させることで、エンゲージメントの高いパーソナライズされた健康・フィットネスアプリケーションを作成するための無限の可能性が開けます。react-native-healthのようなライブラリを使用し、カスタムフック内にロジックをカプセル化することで、ネイティブ設定と権限の複雑さをクリーンで再利用可能なコードで管理できます。
これで、以下の方法を学びました:
- HealthKit capabilityでXcodeを設定する方法。
- 必要な
Info.plist権限を設定する方法。 react-native-healthを使用してユーザーの認証をリクエストする方法。- 歩数、睡眠、ワークアウトなどの主要な健康メトリクスを読み書きする方法。
- カスタムフックでコードをスケーラブルな方法で構成する方法。
リソース
- 公式
react-native-healthドキュメント:GitHub Repository - AppleのHealthKitドキュメント:Apple Developer
- HealthKit設定ガイド:Apple Developer
クイックリファレンス
| 項目 | 重要な情報 |
|---|---|
| トピック | 開発 |
| 関連性 | 患者教育と認識向上 |
| 行動 | 医療提供者にご相談ください |
| 頻度 | ケアチーム推奨に従う |
| 証拠 | 現在の臨床ガイドラインに基づく |
よくある質問
Q: これが自分に該当するかはどうすればわかりますか? A: 個人的な病歴と家族歴について医療提供者と相談し、個人のリスク因子を評価し、適切な次のステップを決定してください。
Q: 医師に何と聞けばよいですか? A: 良い質問例:「結果は何を意味していますか?」「オプションは何がありますか?」「どんなライフスタイルの変更が役に立ちますか?」「いつフォローアップすべきですか?」
Q: 生活を改善するためのライフスタイルの変更はありますか? A: ほとんどの健康状態は、基本的な対策から恩恵を受けます:バランスの取れた栄養、定期的な運動(週150分以上)、質の良い睡眠(7〜9時間)、ストレス管理、そして禁煙。
医療に関する免責事項
この記事は教育目的のみを目的としており、医学的アドバイスを提供するものではありません。健康、治療、またはケアに関する決定を行う前は、常に資格のある医療提供者に相談してください。個々の状況は異なり、1人に適切なことが別の人にも適切なわけではありません。
救急の場合は、直ちに119番(または現地の緊急番号)に連絡してください。