[iOS 8] HealthKitを実装する(2) HealthStoreへデータを保存する

2014.09.18

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

HealthStoreにデータを永続化する実装例

実際に体温をHealthStoreに永続化するサンプルを作ってみます。

HealthKitを使用するクラスファイルではHealthKit.frameworkをインポートする必要があります。HealthKit.frameworkはHealthKitの有効化と同時にプロジェクトへ追加されます。以下のようにクラスファイルの先頭で宣言して下さい。

import HealthKit

※事前に、StoryboardからUITextFieldのtfBodyTemperatureをIBOutletで接続してあります。

/**
引数に渡された文字列を指定のデータへ変換してHealthStoreへ永続化します。
渡される文字列は、Double型へキャスト出来る形式である必要があります。

:param: unit       健康情報の単位型
:param: type       健康情報のデータ型
:param: valueStr   データ文字列
:param: completion 永続化処理完了時に実行される処理
*/
func saveHealthValueWithUnit(unit: HKUnit! , type: HKQuantityType!, valueStr: NSString!, completion: ((success: Bool, error: NSError!) -> Void)) {
    // 保存領域オブジェクトをインスタンス化します。
    let healthStore: HKHealthStore = HKHealthStore()
    
    // 数値オブジェクトを生成します。単位と値が入ります。
    let quantity: HKQuantity = HKQuantity(unit: unit, doubleValue: valueStr.doubleValue)
    
    // HKObjectのサブクラスである、HKQuantitySampleオブジェクトを生成します。
    // 計測の開始時刻と終了時刻が同じ場合は同じ値を設定します。
    let sample: HKQuantitySample = HKQuantitySample(type: type, quantity: quantity, startDate: NSDate(), endDate: NSDate())
    
    // 健康情報のデータ型を保持したNSSetオブジェクトを生成します。
    // 永続化したい情報が複数ある場合はobjectに複数のデータ型配列を設定します。
    let types: NSSet! = NSSet(object: type)
    
    let authStatus:HKAuthorizationStatus = healthStore.authorizationStatusForType(type)
    
    if authStatus == .SharingAuthorized {
        healthStore.saveObject(sample, withCompletion:completion)
    } else {
        
        // 体温型のデータをHealthStoreに永続化するために、ユーザーへ許可を求めます。
        // 許可されたデータのみ、アプリケーションからHealthStoreへ書き込みする権限が与えられます。
        // ヘルスケアの[ソース]タブ画面がモーダルで表示されます。
        // 第1引数に指定したNSSet!型のshareTypesの書き込み許可を求めます。
        // 第2引数に指定したNSSet!型のreadTypesの読み込み許可を求めます。

        healthStore.requestAuthorizationToShareTypes(types, readTypes: types) {
            success, error in
            
            if error != nil {
                NSLog(error.description);
                return
            }
            
            if success {
                NSLog("保存可能");
                healthStore.saveObject(sample, withCompletion:completion)
            }
        }
    }
}

func saveBodyTemperature() {
    let textStr: NSString! = NSString(format: "\(tfBodyTemperature.text)")
    // 体温の単位を生成します。単位は℃(摂氏)です。
    let btUnit: HKUnit! = HKUnit.degreeCelsiusUnit()
    // 体温情報の型を生成します。
    let btType: HKQuantityType! = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyTemperature)
    
    // 永続化処理完了時に非同期で呼び出されます。
    saveHealthValueWithUnit(btUnit, type: btType, valueStr: textStr, completion: {
        success, error in
        
        if error != nil {
            NSLog(error.description)
            return
        }
        
        if success {
            NSLog("体温データの永続化に成功しました。")
        }
    })
}

実行される順に、各処理を解説します。


saveBodyTemperature()

テキストフィールドに入力された文字列と、体温データの情報を元にsaveHealthValueWithUnit(unit: HKUnit! , type: HKQuantityType!, valueStr: NSString!, completion: ((success: Bool, error: NSError!) -> Void))を呼び出しています。永続化したいデータによってこちらのメソッドを変えると良いでしょう。

saveHealthValueWithUnit(unit: HKUnit! , type: HKQuantityType!, valueStr: NSString!, completion: ((success: Bool, error: NSError!) -> Void))

一連の永続化処理を実行します。

let authStatus:HKAuthorizationStatus = healthStore.authorizationStatusForType(type)

アプリケーションがHealthStoreの共有領域にアクセスする権限があるかを確認します。

HKAuthorizationStatusには

  • NotDetermined
  • SharingDenied
  • SharingAuthorized

こちらの3つが存在します。

healthStore.requestAuthorizationToShareTypes(types, readTypes: types)

ユーザーのHealthStoreにアプリケーションが書き込みをする事を確認します。

こちらのメソッドの第1引数にHKObjectTypeが含まれたNSSet!型のオブジェクトを指定します。

ユーザーは、typesに含まれたそれぞれのデータ書き込み権限を設定することが出来ます。書き込みのみ・読み込みのみの場合は該当する引数をnilにして下さい。

healthStore.saveObject(sample, withCompletion:completion)

ユーザーが保存を許可した際に、HealthStoreへHKQuantitySampleオブジェクトを永続化しています。

保存完了時にcompletionメソッドが実行されます。

completion(success: Bool, error: NSError!)

HKQuantitySampleオブジェクトの永続化に成功したら、その旨のログを表示しています。


複数のobjectを同時に永続化したい場合は、healthStore.saveObject()メソッドではなく、healthStore.saveObjects()メソッドを使用して下さい。

saveBodyTemperature()メソッドを任意のタイミングで呼び出す事によって、テキストフィールドへ入力された体温値が永続化されます。

入力された体温値がDouble型へ適切にキャストされる必要があります。

HealthStoreへは適切な型で保存処理を行わなければ、エラーが返されますので注意して下さい。

永続化したデータは「ヘルスケア」アプリの「体温」で確認が行えます。

脚注