次の方法で共有


Xamarin.iOS の HealthKit

Health Kit には、ユーザーの正常性関連情報のためのセキュリティで保護されたデータストアが用意されています。 Health Kit アプリは、ユーザーの明示的なアクセス許可があれば、このデータストアの読み取りと書き込みを行い、関連データが追加されたときに通知を受け取ることができます。 アプリでこのデータを表示できます。また、ユーザーは Apple が提供する正常性アプリを使ってすべてのデータのダッシュボードを表示できます。

健康関連データは非常に機密性が高く重要であるため、Health Kit は厳密に型指定され、測定単位と、記録される情報の種類 (血糖値や心拍数など) との明示的な関連付けが指定されています。 さらに、Health Kit アプリは明示的なエンタイトルメントを使用し、特定の種類の情報へのアクセスを要求する必要があります。また、ユーザーはアプリにこれらの種類のデータへのアクセス権を明示的に付与する必要があります。

この記事では、以下について説明します:

  • Health Kit のセキュリティ要件 (アプリケーションのプロビジョニングや Health Kit データベースへのアクセス許可の要求を含む)。
  • Health Kit の型システム (データの誤適用や誤解釈の可能性を最小限に抑えます)。
  • システム全体の共有 Health Kit データストアへの書き込み。

この記事では、データベースのクエリ、測定単位間の変換、新しいデータに関する通知の受信など、より高度なトピックについては説明しません。

この記事では、ユーザーの心拍数を記録するサンプル アプリケーションを作成します:

ユーザーの心拍数を記録するサンプル アプリケーション

要件

この記事で説明する手順を完了するには、次のものが必要です:

  • Xcode 7 および iOS 8 (またはそれ以降) – Apple の最新の Xcode および iOS API を開発者のコンピューターにインストールして構成する必要があります。
  • Visual Studio for Mac または Visual Studio – 最新バージョンの Visual Studio for Mac を開発者のコンピューターにインストールして構成する必要があります。
  • iOS 8 (またはそれ以降) デバイス – 最新バージョンの iOS 8 以降を実行しているテスト用の iOS デバイス。

重要

Health Kit は iOS 8 で導入されました。 現在、Health Kit は iOS シミュレーターでは使用できません。デバッグには物理的な iOS デバイスへの接続が必要です。

Health Kit アプリの作成とプロビジョニング

Xamarin iOS 8 アプリケーションで HealthKit API を使用するには、適切に構成してプロビジョニングする必要があります。 このセクションでは、Xamarin アプリケーションを適切にセットアップするために必要な手順について説明します。

Health Kit アプリには次のものが必要です:

  • 明示的な アプリ ID
  • その明示的なアプリ ID に関連付けられていて、Health Kit のアクセス許可を持つ プロビジョニング プロファイル
  • Booleancom.apple.developer.healthkit プロパティが Yes に設定されている Entitlements.plist
  • Stringhealthkit を持つエントリが UIRequiredDeviceCapabilities キーに含まれている Info.plist
  • また、Info.plist には適切なプライバシーの説明エントリも必要です: アプリがデータを書き込む場合はキー NSHealthUpdateUsageDescriptionString の説明、アプリが Health Kit データを読み取る場合はキー NSHealthShareUsageDescriptionString の説明です。

iOS アプリのプロビジョニングの詳細については、Xamarin の概要シリーズの「デバイス プロビジョニング」の記事で、開発者証明書、アプリ ID、プロビジョニング プロファイル、アプリ エンタイトルメントの関係が説明されています。

明示的なアプリ ID とプロビジョニング プロファイル

明示的なアプリ ID と適切なプロビジョニング プロファイルの作成は、Apple の iOS Dev Center 内で行われます。

現在のアプリ ID は、Dev Center の証明書、識別子、プロファイルセクションの一覧に表示されます。 多くの場合、この一覧には *ID の値が表示 され、任意の数のサフィックスでアプリ ID - を使用できることを示します。 このようなワイルドカード アプリ ID は、Health Kit では使用できません。

明示的なアプリ ID を作成するには、右上の [+] ボタンをクリックして iOS アプリ ID の登録ページに移動します:

Apple 開発者ポータルでアプリを登録する

上の図のように、アプリの説明を作成した後、明示的なアプリ ID セクションを使用して、アプリケーションの ID を作成します。 App Services セクションで、サービスの有効化セクションの [Health Kit] にチェックを入れます。

完了したら、[続行] ボタンを押して、アカウントにアプリ ID を登録します。 証明書、識別子、プロファイルページに戻ってきます。 [プロビジョニング プロファイル] をクリックして現在のプロビジョニング プロファイルの一覧に移動し、右上にある [+] ボタンをクリックすると、iOS プロビジョニング プロファイルの追加ページに移動します。 [iOS アプリの開発] オプションを選択し、[続行] をクリックしてアプリ ID の選択ページに移動します。 ここで、前に指定した明示的なアプリ ID を選択します:

明示的なアプリ ID を選択する

[続行] をクリックし、残りの画面でこのプロビジョニング プロファイル開発者証明書デバイス名前を指定します:

プロビジョニング プロファイルを生成する

[生成] をクリックし、プロファイルが作成されるまで待ちます。 ファイルをダウンロードし、ダブルクリックして Xcode にインストールします。 [Xcode] > [設定] > [アカウント] > {詳細の表示...} でインストールを確認できます。インストールしたプロビジョニング プロファイルが表示され、Health Kit とその他の特別なサービスのアイコンがエンタイトルメント行に表示されます:

Xcode でのプロファイルの表示

アプリ ID およびプロビジョニング プロファイルと Xamarin.iOS アプリの関連付け

説明に従って適切なプロビジョニング プロファイルを作成してインストールしたら、通常は Visual Studio for Mac または Visual Studio でソリューションを作成します。 Health Kit には、いずれの iOS C# または F# プロジェクトでもアクセスできます。

Xamarin iOS 8 プロジェクトを手動で作成するプロセスを説明するのではなく、この記事に添付されているサンプル アプリ (事前構築済みのストーリーボードとコードを含む) を開きます。 サンプル アプリを Health Kit 対応のプロビジョニング プロファイルに関連付けるには、Solution Pad でプロジェクトを右クリックし、オプション ダイアログを表示します。 iOS アプリケーション パネルに切り替え、前に作成した明示的なアプリ ID をアプリのバンドル識別子として入力します:

明示的なアプリ ID を入力する

ここで、iOS バンドル署名パネルに切り替えます。 最近インストールしたプロビジョニング プロファイルが、明示的なアプリ ID と関連付けられ、プロビジョニング プロファイルとして使用できるようになります:

プロビジョニング プロファイルを選択する

プロビジョニング プロファイルが使用できない場合は、iOS アプリケーション パネルのバンドル識別子iOS Dev Center で指定されているバンドル識別子が一致していて、プロビジョニング プロファイルがインストールされていることを再確認します ([Xcode] > [設定] > [アカウント] > [詳細の表示...])。

Health Kit 対応プロビジョニング プロファイルが選択されている場合は、[OK] をクリックしてプロジェクト オプション ダイアログを閉じます。

Entitlements.plist と Info.plist の値

サンプル アプリには、(Health Kit 対応アプリに必要な) Entitlements.plist ファイルが含まれており、これはすべてのプロジェクト テンプレートに含まれているわけではありません。 プロジェクトにエンタイトルメントが含まれていない場合は、プロジェクトを右クリックし、[ファイル] > [新規ファイル...] > [iOS] > [Entitlements.plist] を選択 して手動で追加します。

最終的に、Entitlements.plist には次のキーと値の組み合わせが必要です:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.developer.HealthKit</key>
    <true/>
</dict>
</plist>

同様に、アプリの Info.plist には UIRequiredDeviceCapabilities キーに関連付けられている healthkit の値が必要があります:

<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
    <string>healthkit</string>
</array>

この記事で提供されるサンプル アプリケーションには、必要なすべてのキーを含む構成済みの Entitlements.plist が含まれています。

Health Kit のプログラミング

Health Kit データストアは、アプリ間で共有されるプライベートなユーザー固有のデータストアです。 健康情報は非常に機密性が高いため、ユーザーはデータ アクセスを許可するために肯定的な手順を実行する必要があります。 このアクセスは部分的なアクセス (書き込みはできても読み取りはできない、一部の種類のデータにはアクセスできても他のデータにはアクセスできないなど) にすることができ、いつでも取り消すことができます。 Health Kit アプリケーションは、多くのユーザーが自分の健康関連情報を保存することをためらうという前提で、防御的に作成する必要があります。

Health Kit のデータは、Apple で指定された型に制限されます。 これらの型は厳密に定義されています。血液型など、Apple が提供する列挙型の特定の値に制限されているものもあれば、大きさと測定単位 (グラム、カロリー、リットルなど) を組み合わせたものもあります。 互換性のある測定単位を共有するデータでも、HKObjectType で区別されます。たとえば、型システムは、両方の測定単位に HKUnit.Count が使用されていても、HKQuantityTypeIdentifier.FlightsClimbed のフィールドに誤って HKQuantityTypeIdentifier.NumberOfTimesFallen の値を格納 しようとした場合にそれを検出します。

Health Kit データストアに格納できる型はすべて、HKObjectType のサブクラスです。 HKCharacteristicType オブジェクトは、生物学的性別、血液型、生年月日を格納します。 ただし、より一般的なのは、特定の時刻または一定期間にわたりサンプリングされるデータを表す、HKSampleType オブジェクトです。

HKSampleType オブジェクト グラフ

HKSampleType は抽象クラスであり、4 つの具象サブクラスを持っています。 現在、HKCategoryType データの型は 1 つだけで、睡眠分析です。 Health Kit のデータの大部分は型 HKQuantityType のもので、データを HKQuantitySample オブジェクトに格納します。これは、使い慣れたファクトリ設計パターンを使用して作成されます:

Health Kit のデータの大部分は HKQuantityType 型であり、そのデータを HKQuantitySample オブジェクトに格納します

HKQuantityType 型の範囲は HKQuantityTypeIdentifier.ActiveEnergyBurned から HKQuantityTypeIdentifier.StepCount までです。

ユーザーへのアクセス許可の要求

エンド ユーザーは、アプリで Health Kit データの読み取りまたは書き込みを行うために、肯定的な手順を実行する必要があります。 これは、iOS 8 デバイスにプレインストールされている Health アプリを介して行われます。 Health Kit アプリを初めて実行すると、ユーザーにシステム制御の健康情報へのアクセス ダイアログが表示されます:

ユーザーには、システムが制御する [Health Access] (Health へのアクセス) ダイアログが表示されます

ユーザーは、後で Health アプリのソース ダイアログを使用してアクセス許可を変更できます:

ユーザーは、後で Health アプリの [Sources] (ソース) ダイアログを使用してアクセス許可を変更できます

健康情報は非常に機密性が高いため、アプリ開発者は、アプリの実行中にアクセス許可が拒否されたり、変更されたりすることを前提に、プログラムを防御的に作成する必要があります。 最も一般的なイディオムでは、UIApplicationDelegate.OnActivated メソッドでアクセス許可を要求し、必要に応じてユーザー インターフェイスを変更します。

アクセス許可のチュートリアル

Health Kit でプロビジョニングされたプロジェクトで、AppDelegate.cs ファイルを開きます。 ステートメントでは、ファイルの先頭に HealthKit を使用 しています。

次のコードは、Health Kit のアクセス許可に関連しています:

private HKHealthStore healthKitStore = new HKHealthStore ();

public override void OnActivated (UIApplication application)
{
        base.OnActivated(application);
        ValidateAuthorization ();
}

private void ValidateAuthorization ()
{
        var heartRateId = HKQuantityTypeIdentifierKey.HeartRate;
        var heartRateType = HKObjectType.GetQuantityType (heartRateId);
        var typesToWrite = new NSSet (new [] { heartRateType });
        var typesToRead = new NSSet ();
        healthKitStore.RequestAuthorizationToShare (
                typesToWrite, 
                typesToRead, 
                ReactToHealthCarePermissions);
}

void ReactToHealthCarePermissions (bool success, NSError error)
{
        var access = healthKitStore.GetAuthorizationStatus (HKObjectType.GetQuantityType (HKQuantityTypeIdentifierKey.HeartRate));
        if (access.HasFlag (HKAuthorizationStatus.SharingAuthorized)) {
                HeartRateModel.Instance.Enabled = true;
        } else {
                HeartRateModel.Instance.Enabled = false;
        }
}

これらのメソッド内のすべてのコードは OnActivated でインラインで実行できますが、サンプル アプリでは、意図をより明確にするために別のメソッドを使用しています: ValidateAuthorization() には書き込まれる (およびアプリで必要な場合は読み取られる) 特定の型へのアクセスを要求するために必要な手順が含まれ、ReactToHealthCarePermissions() はユーザーが Health.アプリのアクセス許可ダイアログを操作した後にアクティブ化されるコールバックです。

ValidateAuthorization() の役割は、アプリが書き込む HKObjectTypes のセットを構築し、そのデータを更新するための認可を要求することです。 サンプル アプリでは、HKObjectType はキー KHQuantityTypeIdentifierKey.HeartRate 用です。 この型はセット typesToWrite に追加されますが、セット typesToRead は空のままです。 これらのセットと ReactToHealthCarePermissions() コールバックへの参照が、HKHealthStore.RequestAuthorizationToShare() に渡されます。

ReactToHealthCarePermissions() コールバックは、ユーザーがアクセス許可ダイアログを操作した後に呼び出され、次の 2 つの情報が渡されます。1 つは、ユーザーがアクセス許可ダイアログを操作した場合に true となる bool の値で、もう 1 つは、null 以外の場合、アクセス許可ダイアログの表示に関連する何らかのエラーを示す NSError です。

重要

この関数の引数について明確にするために、success および error パラメータは、ユーザーが Health Kit データへのアクセス許可を付与したかどうかを示すものではありません。 ユーザーにデータへのアクセスを許可する機会が与えられたことを示すだけです。

アプリがデータにアクセスできるかどうかを確認するには、HKHealthStore.GetAuthorizationStatus() が使用され、HKQuantityTypeIdentifierKey.HeartRate で渡されます。 返された状態に基づいて、アプリはデータを入力する機能を有効または無効にします。 アクセス拒否に対処するための標準的なユーザー エクスペリエンスはなく、多くのオプションが考えられます。 サンプル アプリでは、状態が HeartRateModel シングルトン オブジェクトに設定され、それにより関連するイベントが発生します。

モデル、ビュー、コントローラー

HeartRateModel シングルトン オブジェクトを確認するには、HeartRateModel.cs ファイルを開きます:

using System;
using HealthKit;
using Foundation;

namespace HKWork
{
        public class GenericEventArgs<T> : EventArgs
        {
                public T Value { get; protected set; }
                public DateTime Time { get; protected set; }

                public GenericEventArgs (T value)
                {
                        this.Value = value;
                        Time = DateTime.Now;
                }
        }

        public delegate void GenericEventHandler<T> (object sender,GenericEventArgs<T> args);

        public sealed class HeartRateModel : NSObject
        {
                private static volatile HeartRateModel singleton;
                private static object syncRoot = new Object ();

                private HeartRateModel ()
                {
                }

                public static HeartRateModel Instance {
                        get {
                                //Double-check lazy initialization
                                if (singleton == null) {
                                        lock (syncRoot) {
                                                if (singleton == null) {
                                                        singleton = new HeartRateModel ();
                                                }
                                        }
                                }

                                return singleton;
                        }
                }

                private bool enabled = false;

                public event GenericEventHandler<bool> EnabledChanged;
                public event GenericEventHandler<String> ErrorMessageChanged;
                public event GenericEventHandler<Double> HeartRateStored;

                public bool Enabled { 
                        get { return enabled; }
                        set {
                                if (enabled != value) {
                                        enabled = value;
                                        InvokeOnMainThread(() => EnabledChanged (this, new GenericEventArgs<bool>(value)));
                                }
                        }
                }

                public void PermissionsError(string msg)
                {
                        Enabled = false;
                        InvokeOnMainThread(() => ErrorMessageChanged (this, new GenericEventArgs<string>(msg)));
                }

                //Converts its argument into a strongly-typed quantity representing the value in beats-per-minute
                public HKQuantity HeartRateInBeatsPerMinute(ushort beatsPerMinute)
                {
                        var heartRateUnitType = HKUnit.Count.UnitDividedBy (HKUnit.Minute);
                        var quantity = HKQuantity.FromQuantity (heartRateUnitType, beatsPerMinute);

                        return quantity;
                }
                        
                public void StoreHeartRate(HKQuantity quantity)
                {
                        var bpm = HKUnit.Count.UnitDividedBy (HKUnit.Minute);
                        //Confirm that the value passed in is of a valid type (can be converted to beats-per-minute)
                        if (! quantity.IsCompatible(bpm))
                        {
                                InvokeOnMainThread(() => ErrorMessageChanged(this, new GenericEventArgs<string> ("Units must be compatible with BPM")));
                        }

                        var heartRateId = HKQuantityTypeIdentifierKey.HeartRate;
                        var heartRateQuantityType = HKQuantityType.GetQuantityType (heartRateId);
                        var heartRateSample = HKQuantitySample.FromType (heartRateQuantityType, quantity, new NSDate (), new NSDate (), new HKMetadata());

                        using (var healthKitStore = new HKHealthStore ()) {
                                healthKitStore.SaveObject (heartRateSample, (success, error) => {
                                        InvokeOnMainThread (() => {
                                                if (success) {
                                                        HeartRateStored(this, new GenericEventArgs<Double>(quantity.GetDoubleValue(bpm)));
                                                } else {
                                                        ErrorMessageChanged(this, new GenericEventArgs<string>("Save failed"));
                                                }
                                                if (error != null) {
                                                        //If there's some kind of error, disable 
                                                        Enabled = false;
                                                        ErrorMessageChanged (this, new GenericEventArgs<string>(error.ToString()));
                                                }
                                        });
                                });
                        }
                }
        }
}

最初のセクションは、汎用イベントとハンドラーを作成するための定型コードです。 HeartRateModel クラスの最初の部分も、スレッド セーフなシングルトン オブジェクトを作成するための定型コードです。

次に、HeartRateModel が 3 つのイベントを公開します:

  • EnabledChanged - 心拍数ストレージが有効または無効になったことを示します (ストレージは最初に無効になっています)。
  • ErrorMessageChanged - このサンプル アプリでは、非常にシンプルなエラー処理モデル (最後のエラーを含む文字列) が使用されています。
  • HeartRateStored - 心拍数が Health Kit データベースに格納されたときに発生します。

これらのイベントが発生するたびに、NSObject.InvokeOnMainThread() を介して実行されるため、サブスクライバーが UI を更新できるようになります。 また、イベントはバックグラウンド スレッドで発生していると文書化し、互換性の確保をハンドラーに任せることもできます。 アクセス許可の要求などの多くの関数は非同期であり、メイン以外のスレッドでコールバックを実行するため、Health Kit アプリケーションではスレッドについて考慮することが重要になります。

HeartRateModel の Heath Kit 固有のコードは、HeartRateInBeatsPerMinute()StoreHeartRate().の 2 つの関数です。

HeartRateInBeatsPerMinute() は、その引数を厳密に型指定された Health Kit HKQuantity に変換します。 数量の型は HKQuantityTypeIdentifierKey.HeartRate で指定され、数量の単位は HKUnit.CountHKUnit.Minute で割ったもの (つまり、単位は 1 分あたりの脈拍数) です。

StoreHeartRate() 関数は HKQuantity (サンプル アプリでは HeartRateInBeatsPerMinute() により作成されたもの) を受け取ります。 データを検証するために、HKQuantity.IsCompatible() メソッドを使用します。このメソッドは、オブジェクトの単位を引数の単位に変換できる場合、true を返します。 数量が HeartRateInBeatsPerMinute() で作成された場合、これは明らかに true を返しますが、数量が 1 時間あたりの心拍数などで作成された場合も true を返します。 より一般的に、HKQuantity.IsCompatible() は質量、距離、エネルギーを検証するために使用できます。これは、ユーザーまたはデバイスが 1 つの測定システム (インペリアルなど) で入力または表示し、別のシステム (メトリックなど) で格納される可能性があります。

数量の互換性が検証されると、HKQuantitySample.FromType() ファクトリ メソッドを使用して厳密に型指定された heartRateSample オブジェクトが作成されます。 HKSample オブジェクトには開始日と終了日があります。瞬時に読み取る場合、これらの値は例のように同じである必要があります。 このサンプルでは、HKMetadata 引数でキー値データも設定されていませんが、次のようなコードを使用してセンサーの場所を指定することもできます:

var hkm = new HKMetadata();
hkm.HeartRateSensorLocation = HKHeartRateSensorLocation.Chest;

heartRateSample が作成されると、コードはブロックを使用してデータベースへの新しい接続を作成します。 そのブロック内で、HKHealthStore.SaveObject() メソッドはデータベースへの非同期書き込みを試みます。 その結果、ラムダ式への呼び出しによって、関連するイベント (HeartRateStored または ErrorMessageChanged) がトリガーされます。.

モデルがプログラミングされたので、モデルの状態がコントローラーにどのように反映されるかを確認します。 ファイル HKWorkViewController.cs を開きます。 コンストラクターは単に HeartRateModel シングルトンをイベント処理メソッドに結び付けます (この場合も、ラムダ式を使用してインラインで行うことができますが、別のメソッドによって意図が少し明確になります):

public HKWorkViewController (IntPtr handle) : base (handle)
{
     HeartRateModel.Instance.EnabledChanged += OnEnabledChanged;
     HeartRateModel.Instance.ErrorMessageChanged += OnErrorMessageChanged;
     HeartRateModel.Instance.HeartRateStored += OnHeartBeatStored;
}

関連するハンドラーを次に示します:

void OnEnabledChanged (object sender, GenericEventArgs<bool> args)
{
        StoreData.Enabled = args.Value;
        PermissionsLabel.Text = args.Value ? "Ready to record" : "Not authorized to store data.";
        PermissionsLabel.SizeToFit ();
}

void OnErrorMessageChanged (object sender, GenericEventArgs<string> args)
{
        PermissionsLabel.Text = args.Value;
}

void OnHeartBeatStored (object sender, GenericEventArgs<double> args)
{
        PermissionsLabel.Text = String.Format ("Stored {0} BPM", args.Value);
}

もちろん、単一のコントローラーを持つアプリケーションでは、別のモデル オブジェクトの作成と制御フローのイベントの使用を避けることはできますが、モデル オブジェクトの使用は実際のアプリにより適しています。

サンプル アプリの実行

iOS シミュレーターは Health Kit をサポートしていません。 デバッグは、iOS 8 を実行している物理デバイスで行う必要があります。

適切にプロビジョニングされた iOS 8 開発デバイスをシステムに接続します。 Visual Studio for Mac でデプロイ ターゲットとして選択し、メニューから [実行] > [デバッグ] を選択します。

重要

プロビジョニングに関する間違いは、この時点で浮上します。 エラーのトラブルシューティングを行うには、上記の Health Kit アプリの作成とプロビジョニング セクションを確認してください。 コンポーネントは次のとおりです。

  • iOS Dev Center - 明示的なアプリ ID と Health Kit 対応プロビジョニング プロファイル。
  • プロジェクト オプション - バンドル識別子 (明示的なアプリ ID) とプロビジョニング プロファイル。
  • ソース コード - Entitlements.plist と Info.plist

プロビジョニングが適切に設定されていれば、アプリケーションが起動します。 OnActivated メソッドに達すると、Health Kit の認可が要求されます。 これがオペレーティング システムによって初めて検出されると、ユーザーに次のダイアログが表示されます:

ユーザーにこのダイアログが表示されます

アプリが心拍数データを更新できるようにすると、アプリが再び表示されます。 ReactToHealthCarePermissions コールバックは非同期的にアクティブ化されます。 これにより、 HeartRateModel’s Enabled プロパティが変更され、 EnabledChanged イベントが発生し、 HKPermissionsViewController.OnEnabledChanged() イベント ハンドラーが実行され、 StoreData ボタンが有効になります。 次の図は、シーケンスを示しています:

この図は、イベントのシーケンスを示しています

[記録] ボタンを押します。 これにより、StoreData_TouchUpInside() ハンドラーが実行され、heartRate テキスト フィールドの値の解析を試み、前に説明した HeartRateModel.HeartRateInBeatsPerMinute() 関数を介して HKQuantity に変換し、その数量を HeartRateModel.StoreHeartRate().に渡します。 前に説明したように、これはデータの格納を試み、HeartRateStored または ErrorMessageChanged イベントを発生させます。

デバイスのホームボタンをダブルクリックし、Health アプリを開きます。 [ソース] タブをクリックすると、サンプル アプリが一覧に表示されます。 それを選択し、心拍数データを更新するアクセス許可を無効にします。 ホームボタンをダブルクリックし、再びアプリに切り替えます。 もう一度 ReactToHealthCarePermissions() が呼び出されますが、今回はアクセスが拒否されるため、[StoreData] ボタンは無効になります (これは非同期的に発生し、ユーザー インターフェイスの変更がエンド ユーザーに表示される可能性があります)。

高度なトピック

Health Kit データベースからのデータの読み取りは、データの書き込みとよく似ています。1 つはアクセスしようとしているデータの型を指定し、認可を要求します。認可が得られた場合は、互換性のある測定単位に自動的に変換され、データを使用できます。

述語ベースのクエリと、関連するデータが更新されたときに更新を実行するクエリを使用できる、より高度なクエリ関数がいくつかあります。

Health Kit アプリケーションの開発者は、Apple の「アプリ レビュー ガイドライン」の Health Kit セクションを確認する必要があります。

セキュリティと型システム モデルを理解すれば、共有 Health Kit データベースにデータを格納して読み取るのはとても簡単です。 Health Kit 内の関数の多くは非同期的に動作し、アプリケーション開発者はプログラムを適切に作成する必要があります。

この記事の執筆時点では、現在、Android または Windows Phone の Health Kit に相当する機能はありません。

まとめ

この記事では、Health Kit がアプリケーションによる健康関連情報の格納、取得、共有を可能にすると同時に、ユーザーがこのデータにアクセスして制御できるようにする標準の Health アプリを提供することについて説明しました。

また、健康関連情報ではプライバシー、セキュリティ、データの整合性が大きな懸念事項となり、Health Kit を使用するアプリはアプリケーション管理の側面 (プロビジョニング)、コーディング (Health Kit の型システム)、ユーザー エクスペリエンス (システム ダイアログと Health アプリによるアクセス許可のユーザー制御) の複雑さの増加に対処する必要があることも指摘しました。

最後に、Health Kit ストアに心拍数データを書き込み、非同期を意識して設計された、付属のサンプル アプリを使用して、Health Kit のシンプルな実装例もご紹介しました。