ヘルスケア連携するにあたり、HealthKit の認証処理って、他の Framework よりもわかりづらいなーと感じたので、ちょいとまとめます。
前提条件
・Xcode11.3
・Swift5
・ヘルスケアAppで自身のデータを設定済み
【2020年8月7日】Xcode11.6 で動作確認
認証関連処理
HealthKit に対応しているデバイスか確認
1 2 3 4 5 |
if HKHealthStore.isHealthDataAvailable() { print("対応") } else { print("非対応") } |
端末を変えない限り、このステータスが変わることはないです。
執筆時では iPad はヘルスケアに対応していないので、必ず false になります。
br>
br>
ヘルスケアデータへのアクセス許可をリクエスト
1 2 3 4 5 6 7 8 9 |
// self.shareList と self.readList は Set<HKSampleType> で定義されてるとします let healthStore = HKHealthStore() healthStore.requestAuthorization(toShare: self.shareList, read: self.readList, completion: { (success, error) in if success { print("リクエスト成功") } else { print("リクエスト失敗") } }) |
これをコールすると、Apple お手製の下のような画面が呼ばれます。
認証の可否に関わらず、ユーザーが一度でも処理をすると表示されなくなりますが、
・アプリを再インストールする
・新しい権限を追加したとき
どちらかが行われた場合は、再度表示されます。
また、戻り値の success ですが、これはアクセス許可の可否ではありません。
リクエストが成功したかどうかなので、基本的には成功すると思います。
ユーザーがアクセスを拒否しても、true が返ってきますので、混乱しないようにしましょう!
br>
br>
リクエストしたアクセス許可の可否
アクセス許可の可否を一度に確認できるメソッドやプロパティは用意されていません。
一つ一つ確認する必要があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// self.shareList は Set<HKSampleType> で定義されてるとします for sampleType in self.shareList { let authorized = self.healthStore.authorizationStatus(for: sampleType) switch authorized { case .sharingAuthorized: print("許可") case .sharingDenied: print("拒否") case .notDetermined: print("未選択") @unknown default: break } } } |
必要なアクセスだけを確認する方が、Apple的にも処理が重くならなくていいのかもしれません。
新しくアクセス許可をしたい場合
アクセス許可をリクエスト済みで、新しく「消費エネルギー」や「体重」などを追加で許可してほしいときは、最初の ヘルスケアデータへのアクセス許可をリクエスト で載せた方法を実行するだけで、差分のアクセス許可だけリクエストしてくれます。
ただ、アプリに実装する場合、急にリクエスト画面が出るのは良くないです。
バッジを点けるとかアラートを出すとか、知らせるほうがベストだと思います。
そんなときに活躍するメソッドがこちら。
1 2 3 4 5 6 7 8 9 10 11 12 |
let healthStore = HKHealthStore() healthStore.getRequestStatusForAuthorization(toShare: self.shareList, read: self.readList) { (authorized, error) in switch authorized { case .shouldRequest: // アクセス許可に差分があるとき case .unnecessary: // 差分なし default: break } } } |
これを使って「再度ヘルスケア連携をしてね!」的なことを知らせる方がベストかと | ・ω・`)
さいごに
ヘルスケア関連の情報は、プライバシー確保のために開発者でさえ取得できない情報もあって、不便だなーと思いつつも、安心感あって好きになったな ᕕ( ͡° ͜ʖ ͡°)ᕗ
コメント