[iOS 8] HealthKitを実装する(1) HealthKit簡易リファレンス

HealthKitを使う

HealthKitを使ったアプリの実装方法について紹介します。

HealthKitではiOS 8ユーザーの健康に関する情報を、アプリ間を跨いだ共有の保存領域(HealthStore)で永続化することができます。

あらかじめHealthKitで指定された値を各々のアプリケーションから永続化することで、プリインストールされている「ヘルスケア」から一括して参照することが出来ます。

HealthKitを実機で使う準備

Xcodeで作成したプロジェクトのHealthKitを有効にする必要があります。有効化はCapabilitiesのタブから行えます。

helathkit-add-xcode

[Project] → [TARGETS (AppID)] → [Capabilities] → [HealthKit]

の順に選択して有効化して下さい。

HealthKitを使ったアプリをリリースする場合、iOS Dev CenterでApp IDを作成する際にHealthKitの有効化が必要です。

healthkit-apple-dev-center

App ID作成時、忘れずにHealthKitの項目を有効化しましょう。

以上でHealthKitを実装する準備が整いました。

HealthKitが扱うデータ

先にも記述した通り、HealthKitで扱えるデータはあらかじめ決められています。健康に関するデータなら何でも扱えるという訳ではありません。

HealthStore

HealthKitで管理される保存領域をHealthStoreといいます。HealthStoreへのデータの読み書きにはユーザーの認証が必要です。

アプリケーションで、HealthStoreへのデータを読み書きする時に認証を求めるメソッドがあらかじめ用意されています。

この認証で、ユーザーは任意のデータの読み書きを制限することができます。

HealthStoreは以下のように生成します。

let healthStore: HKHealthStore = HKHealthStore()

HKObject

HealthKitで扱えるデータオブジェクトをHKObjectといいます。HealthKitとのデータのやり取りはこのHKObjectを介して行います。

HKObjectは以下の3つで構成されています。

  • UUID

    HealthKitデータベースの一意な識別子を表します。

  • source

    データが提供されたアプリの情報、もしくはデバイスの情報が入ります。

  • metadata

    データ提供元のメタ情報が入ります。メタ情報はDictionary形式で、キーはNSString、値はNSString・NSNumber・NSDateが使えます。

HKUnit

データの単位を示します。例えば、扱うデータが体温だとすると、単位は「摂氏(℃)」となります。

HKUnitは以下のように生成します。

let unit: HKUnit! = HKUnit.degreeCelsiusUnit() // 単位 摂氏の生成
let unit: HKUnit! = HKUnit(fromString: "degC") // 単位 摂氏(degrees Celsius)の生成

単位専用のイニシャライザから生成する方法と、コンストラクタに文字列を指定して生成する方法の2パターンがあります。 それぞれの単位の生成方法についてはHKUnit.hをご覧下さい。

HKQuantity

データの値を示します。例えば、扱うデータが体温だとすると、値は「36.0」となります。

HKQuantity(値)を生成するためにはHKUnit(単位)が必要です。以下のように生成します。

let quantity: HKQuantity = HKQuantity(unit: myUnit, doubleValue: 36.0)

HKObjectType

HealthKitデータの種類を示します。データの種類を生成するメソッドは5つ用意されています。

class func quantityTypeForIdentifier(identifier: String!) -> HKQuantityType!
class func categoryTypeForIdentifier(identifier: String!) -> HKCategoryType!
class func characteristicTypeForIdentifier(identifier: String!) -> HKCharacteristicType!
class func correlationTypeForIdentifier(identifier: String!) -> HKCorrelationType!
class func workoutType() -> HKWorkoutType!

それぞれの種類の区分の詳細は以下の通りです。


HKQuantityType

身長・体重・体脂肪率・歩数・消費カロリー・心拍数・体温・栄養

主に数値で換算できる種類です。ほとんどのデータがこれに該当します。

HKCategoryType

2014/09/18 現在ではHKCategoryTypeIdentifierSleepAnalysisのみです。

睡眠に関する種類です。

HKCharacteristicType

生年月日・生物学的性別・血液型

ユーザーの情報です。医療分野で必要になりそうなデータです。2014/09/18 現在では3つのみです。

HKCorrelationType

2014/09/18 現在、HKCorrelationTypeIdentifierBloodPressureとHKCorrelationTypeIdentifierFoodの2つのみです。

相関関係のあるデータがこちらに該当すると思われます。

HKWorkoutType

2014/09/18 現在、HKWorkoutTypeIdentifierのみです。

トラッキングが必要なデータがこちらに該当すると思われます。


例えば、扱うデータが体温だとすると、種類は「HKQuantityType」となります。HKQuantityTypeを生成するには、何のデータを表すかのIDが必要です。以下のように生成します。

let quantityType: HKQuantityType! = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyTemperature)

quantityTypeForIdentifierメソッドの引数にIDを指定します。HKQuantityTypeIdentifierBodyTemperatureは体温のIDです。

それぞれのデータにIDの定数が割り振られています。HKQuantityTypeであればHKQuantityTypeIdentifierまで入力すれば、あとは補完から選べるでしょう。

HKSample

HKSampleはHKObjectを継承したクラスです。HealthStoreとのデータのやり取りをする際のデータを、より具体的に扱えるようにしたクラスです。

HKSampleは以下の3つで構成されています。

  • sampleType

    どんなデータを扱うオブジェクトなのかを表します。

  • startDate

    開始時刻が入ります。計測対象のデータによってはendDateと同じになります。

  • endDate

    終了時刻が入ります。計測対象のデータによってはstartDateと同じになります。

データの種類によってHKSampleオブジェクトのサブクラスが用意されています。

HKQuantitySample

HKQuantityTypeのHKObjectです。各計測データは、HKQuantitySampleを介してHealthStoreとやり取りします。

HKCategorySample

HKCategoryTypeのHKObjectです。睡眠データは、HKCategorySampleを介してHeatlhStoreとやり取りします。

HKQuery

HKObjectをHelthStoreから問い合わせるためのクエリーです。

2014/09/18 現在、以下の7つが用意されています。

HKSampleQuery

永続化されたHKSampleオブジェクトをHealthStoreから問い合わせるクエリーです。

  • Int limit
  • [AnyObject]? sortDescriptors

をプロパティとして保持しています。使い方は後述の実装例を参考にして下さい。

HKObserverQuery

HealthStoreの値の変更を検知するためのクラスです。

コンストラクタにCompletionHandlerを指定して使います。

HKObserverQuery(sampleType: HKSampleType!, predicate: NSPredicate!, updateHandler: ((HKObserverQuery!, HKObserverQueryCompletionHandler!, NSError!) -> Void)!)

HealthStoreの対象のデータが刻々と変化する場合は、こちらのハンドラに登録しておけば変更時にCompletionHandlerが呼び出されます。

ハンドラ内でHKSampleQueryを実行すれば、検索をして値が変わっているかを確認する必要がなくなります。クエリの無駄な発行を抑えることが出来ます。

HKAnchoredObjectQuery

HealthStoreに永続化された値が他のアプリケーションによって更新された時、自分のアプリケーションのデータとの差分を取得できます。

こちらもコンストラクタにCompletionHandlerを指定して使います。

HKAnchoredObjectQuery(type: HKSampleType!, predicate: NSPredicate!, anchor: Int, limit: Int, completionHandler handler: ((HKAnchoredObjectQuery!, [AnyObject]!, Int, NSError!) -> Void)!)

複数のアプリを組み合わせて、同じデータを扱う場合には必要になりそうです。HealthStoreのデータはAnchorの連番によって管理されています。

anchor: Intにはどの時点からの差分を取得するか指定できます。0を指定すると全てのデータが取得できます。

CompletionHandler内で新しく渡されるnewAnchor: Intを保持しておけば、以降は差分データのみを取得できます。

HKObserverQueryと組み合わせることで、特定の時点からの値の変化を、余計な値を取得することなく監視することが出来ます。

HKStatisticsQuery

統計データを取得するために使います。

HKStatisticsQuery(quantityType: HKQuantityType!, quantitySamplePredicate: NSPredicate!, options: HKStatisticsOptions, completionHandler handler: ((HKStatisticsQuery!, HKStatistics!, NSError!) -> Void)!)

数値で計測できるデータのみを対象に限定されています。

第3引数にHKStatisticsOptionsを指定することによって、何を基準に取得するかを指定できます。

  • None(指定なし)
  • SeparateBySource(取得元)
  • DiscreteAverage(平均値)
  • DiscreteMin(最小値)
  • DiscreteMax(最大値)
  • CumulativeSum(合計値)

指定できるHKStatisticsOptionsはデータによって異なります。HKStatisticsOptionsはビットフラグで管理されているので、複数立てることが可能です。

let statisticsOptions: HKStatisticsOptions = HKStatisticsOptions.DiscreteAverage | HKStatisticsOptions.DiscreteMin | HKStatisticsOptions.DiscreteMax

例えば上記のHKStatisticsOptionsを指定すると、全ての体温の平均・最小値・最大値を取得することができます。

HKStatisticsCollectionQuery

1日毎の集計を行いたい場合などは、こちらを使用すると良いでしょう。

HKStatisticsCollectionQuery(quantityType: HKQuantityType!, quantitySamplePredicate: NSPredicate!, options: HKStatisticsOptions, anchorDate: NSDate!, intervalComponents: NSDateComponents!)

anchorDate: NSDate!とintervalComponents: NSDateComponents!を組み合わせる事によって、特定の日付から決められた間隔の集計をすることができます。

例えば、今月の毎日の体温の統計情報を取る事が可能です。

HKSourceQuery

HKSourceQuery(sampleType: HKSampleType!, samplePredicate objectPredicate: NSPredicate!, completionHandler: ((HKSourceQuery!, NSSet!, NSError!) -> Void)!)

HKCorrelationQuery

HKCorrelationQuery(type correlationType: HKCorrelationType!, predicate: NSPredicate!, samplePredicates: [NSObject : AnyObject]!, completion: ((HKCorrelationQuery!, [AnyObject]!, NSError!) -> Void)!)

脚注