【ミーア】AppleHealth Kitの連携状態の取得について:iOSがプライバシーの観点からややこしすぎた
はじめに
前回からAppleHealth Kitとの連携をflutterのhealthパッケージで進めているが、連携状態の取得に関して、iOSの場合がややこしすぎたので(Androidよりもユーザーへのプライバシー配慮が厳しい)備忘録として記載。
flutterのhealthパッケージにhasPermissionメソッドはあるが、実質iOSでは使えない!
Flutter の health パッケージでは、hasPermissions メソッドを提供しており、アプリが特定の健康データへのアクセス権を持っているかどうかを確認することができる。
しかし、iOS では、Apple のプライバシーポリシーにより、HealthKit はアプリが読み取りアクセス権を持っているかどうかをアプリ自体に知らせない(外部に開示しない)。そのため、hasPermissions メソッドは iOS では常に null を返す設計となっている。
これは、ユーザーのプライバシーを保護するための措置だが、開発者はこのメソッドを信頼してユーザーの許可状態を確認することができないという制約がある。
bool? hasPermissions = await health.hasPermissions([HealthDataType.STEPS]);
print('Permissions status: $hasPermissions');
このコードは、ユーザーがステップデータへのアクセスを許可しているかどうかを確認しようとするが、iOS では hasPermissions は、開発者が期待する true/false ではなくnullを返す。ちなみに、Androidでは開発者の期待通り、hasPermissionsメソッドでユーザーの健康データ許可状態を読み取ってtrue/falseで返してくれる。
詳細はこちら参照
hasPermissions の制限への対応
実際のデータアクセスを確認する方法とその実装
hasPermissions が有用な情報を提供しないため、実際にデータを取得しようと試みることで、アクセス権限の有無を間接的に確認することができる。
以下のコードは、過去30日間のステップデータを取得しようと試み、データが取得できれば権限があると判断する。
try {
List<HealthDataPoint> healthData = await health.getHealthDataFromTypes(
DateTime.now().subtract(Duration(days: 30)),
DateTime.now(),
[HealthDataType.STEPS],
);
bool hasPermissions = healthData.isNotEmpty;
print('Permissions status: $hasPermissions');
} catch (e) {
print('Error checking health data access: $e');
}
ユーザーが Health アプリで設定を変更した場合の対応
ユーザーが Health アプリで設定を変更した場合、アプリはその変更を検知できまない。そのため、アプリは定期的にデータアクセスを確認するか、ユーザーがアプリに戻ってきたとき(例えば、AppLifecycleState.resumed で)にデータアクセスを再確認する必要がある。
Dart
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
checkHealthDataAccess();
}
}
WidgetsBinding.instance.addObserver(this) の説明
WidgetsBinding.instance.addObserver(this) は、現在のクラスにライフサイクルイベントの監視を追加するメソッド。このメソッドを使用することで、クラス内で WidgetsBindingObserver プロトコルのメソッドを実装し、アプリの状態変化(例: バックグラウンド移行、フォアグラウンド復帰)を検知できるようになる。これは、特定のアプリ状態に応じて特定の操作を行いたい場合に有用。
続きは、こちらで記載しています。