Xamarin.iOSでヘルスケアと連携
2018年6月14日
プロビジョニングプロファイルで、HealthKitを有効にしてヘルスケアデータを読み込んだり書き込んだりしようと思い。
血圧でつまづいたのでメモ。
1.プロビジョニングプロファイルで、HealthKitを有効にする。
↓を参考に
https://docs.microsoft.com/ja-jp/xamarin/ios/platform/healthkit
2.血圧を読み/書きする。
①最高血圧と最低血圧のアクセス権を取得する
参考サイトの通りだが、HKQuantityTypeIdentifier.BloodPressureDiastolicとHKQuantityTypeIdentifier.BloodPressureSystolicを指定する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
private void ValidateAuthorization() { var typesToWrite = new NSSet(new[] { HKQuantityType.Create(HKQuantityTypeIdentifier.BloodPressureDiastolic)/* 最低血圧 */, HKQuantityType.Create(HKQuantityTypeIdentifier.BloodPressureSystolic)/* 最高血圧 */) }); var typesToRead = new NSSet(new[] { HKQuantityType.Create(HKQuantityTypeIdentifier.BloodPressureDiastolic), HKQuantityType.Create(HKQuantityTypeIdentifier.BloodPressureSystolic)) }); healthKitStore.RequestAuthorizationToShare( typesToWrite, typesToRead, ReactToHealthCarePermissions); } void ReactToHealthCarePermissions(bool success, NSError error) { var access1 = healthKitStore.GetAuthorizationStatus(HKQuantityType.Create(HKQuantityTypeIdentifier.BloodPressureSystolic)); var access2 = healthKitStore.GetAuthorizationStatus(HKQuantityType.Create(HKQuantityTypeIdentifier.BloodPressureDiastolic)); if (access1.HasFlag(HKAuthorizationStatus.SharingAuthorized) && access2.HasFlag(HKAuthorizationStatus.SharingAuthorized)) { Debug.WriteLine("アクセスOK"); } else { Debug.WriteLine("アクセスNG"); } } |
②データ取得
ヘルスケアの変更を監視するので、HKObserverQueryで監視して、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public void StartObserver() { //var quantityType = HKQuantityType.Create(HKQuantityTypeIdentifier.BloodPressureDiastolic);//←最高血圧・最低血圧個別に監視ではなく、 var quantityType = HKCorrelationType.Create(HKCorrelationTypeIdentifier.BloodPressure);//←血圧のくくりで監視 var query = new HKObserverQuery(quantityType, null, (HKObserverQuery resultQuery, Action completion, NSError error) => { if (error != null) { Debug.WriteLine("エラー"); return; } GetBloodPressure(); completion(); }); using (var healthKitStore = new HKHealthStore()) { healthKitStore.ExecuteQuery(query); } } |
通知が来たら、HKAnchoredObjectQueryで差分取得する。
HKCorrelationに最高血圧と最低血圧のコレクションが返ってくるので、QuantityTypeを見てデータとる。
※newAnchorはアプリで覚えておき、次からは指定すると差分でとれる。Anchorはヘルスケアのデータを消しても初期化されないっぽい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
public void GetBloodPressure() { var quantityTypeMin = HKQuantityType.Create(HKQuantityTypeIdentifier.BloodPressureDiastolic); var quantityTypeMax = HKQuantityType.Create(HKQuantityTypeIdentifier.BloodPressureSystolic); //var quantityType = HKQuantityType.Create(HKQuantityTypeIdentifier.BloodPressureDiastolic);//←最高血圧・最低血圧個別でとるのではなく、 var quantityType = HKCorrelationType.Create(HKCorrelationTypeIdentifier.BloodPressure);//←血圧のくくりでとる var query = new HKAnchoredObjectQuery(quantityType, null, (nuint)NewAnchor, 0, (HKAnchoredObjectQuery resultQuery, HKSample[] results, nuint newAnchor, NSError error) => { if (error != null) { Debug.WriteLine("エラー"); return; } if (results.Length != 0) { NewAnchor = (int)newAnchor;//←次の取得のために覚えておく HKQuantity quantity = null; foreach (var result in results) { double max = 0; double min = 0; var date = result.EndDate.NSDateToDateTime(); foreach (var item in ((HKCorrelation)result).Objects) { // 最低血圧 if (((HKQuantitySample)item).QuantityType == quantityTypeMin) { quantity = ((HKQuantitySample)item).Quantity; var unit = HKUnit.MillimeterOfMercury; min = quantity.GetDoubleValue(unit); } // 最高血圧 else if(((HKQuantitySample)item).QuantityType == quantityTypeMax) { quantity = ((HKQuantitySample)item).Quantity; var unit = HKUnit.MillimeterOfMercury; max = quantity.GetDoubleValue(unit); } } Debug.WriteLine($"newAnchor = {newAnchor}, date = {date}, max = {max}, min = {min}"); } } }); using (var healthKitStore = new HKHealthStore()) { healthKitStore.ExecuteQuery(query); } } |
※NSDate⇔DateTimeは↓を参考にした。
https://qiita.com/amay077/items/e6a53081c776a127b41e
④データ書き込み
HKCorrelationに最低血圧・最高血圧のHKQuantitySampleを詰めて書き込む。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
public void StoreBloodPressure(DateTime date, double max, double min) { var quantityTypeMin = HKQuantityType.Create(HKQuantityTypeIdentifier.BloodPressureDiastolic); var quantityTypeMax = HKQuantityType.Create(HKQuantityTypeIdentifier.BloodPressureSystolic); using (var healthKitStore = new HKHealthStore()) { // 最低血圧のHKQuantitySample var quantityMin = HKQuantity.FromQuantity(HKUnit.MillimeterOfMercury, min); var sampleMin = HKQuantitySample.FromType(quantityTypeMin, quantityMin, date.DateTimeToNSDate(), date.DateTimeToNSDate()); // 最高血圧のHKQuantitySample var quantityMax = HKQuantity.FromQuantity(HKUnit.MillimeterOfMercury, max); var sampleMax = HKQuantitySample.FromType(quantityTypeMax, quantityMax, date.DateTimeToNSDate(), date.DateTimeToNSDate()); // 血圧のHKCorrelation var type = HKCorrelationType.Create(HKCorrelationTypeIdentifier.BloodPressure); var samples = new HKSample[] { sampleMax, sampleMin }; var set = NSSet.MakeNSObjectSet<HKSample>(samples); var crrelation = HKCorrelation.Create(type, date.DateTimeToNSDate(), date.DateTimeToNSDate(), set); // Save healthKitStore.SaveObject(crrelation, (success, error) => { if (success) { Debug.WriteLine("Saveしました"); } else { Debug.WriteLine("Save失敗"); } if (error != null) { Debug.WriteLine("エラー"); } }); } } |
登録できた。
が、なぜか個別で登録したデータが消せない。。(´^`)
範囲指定?みたいなことになっている感じだなぁ。ヘルスケア側いじったんだっけかなぁ。。
—
参考サイト