Swift watchOS で ヘルスデータを登録する
1.ヘルスデータをhealthkitに保存する
アプリは新しいサンプルを作成し、HealthKitストアに追加することができます。すべてのサンプルタイプは同様の手順を踏みますが、各タイプには独自のバリエーションがあります。
- データの型式識別子を調べます。例えば、ユーザーの体重を記録するには、bodyMass 型の識別子を使用します。型識別子の完全なリストについては、「データ型」を参照してください。
- HKObjectTypeクラスの便利なメソッドを使用して、データに適したオブジェクト タイプを作成します。
たとえば、ユーザーの体重を保存するには、quantityType(forIdentifier:)メソッドを使用してHKQuantityTypeオブジェクトを作成することになります。
便利なメソッドの一覧は、HKObjectTypeを参照してください。 - 一致する HKSample サブクラスのオブジェクトを、オブジェクト・タイプを使用してインスタンス化します。
- save(_:withCompletion:) メソッドを使用して、HealthKit ストアにオブジェクトを保存します。
各HKSampleサブクラスは、サンプルオブジェクトをインスタンス化するための独自の便利なメソッドを持っており、上記のリストで説明した手順を変更することができます。
1.2 数量サンプルの場合
HKQuantityクラスのインスタンスを作成します。数量の単位は、型識別子のドキュメントに記述されている許容単位に対応する必要があります。たとえば、高さのドキュメントでは、長さの単位を使用することが記載されています。したがって、数量はセンチメートル、メートル、フィート、インチ、またはその他の互換性のある単位を使用する必要があります。詳細については、「HKQuantitySample」を参照してください。
1.3 カテゴリサンプルの場合
サンプルの値は、型識別子のドキュメントに記載されているenumに対応する必要があります。たとえば、sleepAnalysisのドキュメントでは、HKCategoryValueSleepAnalysisのenumを使用することが記載されています。したがって、このサンプルを作成するときは、このenumから値を渡す必要があります。詳細については、「HKCategorySample」を参照してください。
1.4 相関関係
まず、相関関係に含まれるすべてのサンプル・オブジェクトを作成する必要があります。相関のタイプ識別子には、含まれるオブジェクトのタイプと数の両方が記述されています。含まれるオブジェクトは、HealthKit ストアに保存しないでください。それらは相関の一部として保存されます。詳細については、「HKCorrelation」を参照してください。
2.ソース
OKボタン押下にて呼び出される、以下ソースのselectBodyMass()メソッドで保存処理を実行
import WatchKit import Foundation import HealthKit class InterfaceController: WKInterfaceController { @IBOutlet weak var bodyMassPicker: WKInterfacePicker! var items:[WKPickerItem] = [] @IBOutlet weak var selectedBodyMassLabel: WKInterfaceLabel! var selectedBodyMass:String? @IBOutlet weak var healthKitStatus: WKInterfaceTextField! var healthStore : HKHealthStore? override func awake(withContext context: Any?) { // Configure interface objects here. if HKHealthStore.isHealthDataAvailable() { self.healthStore = HKHealthStore() let allTypes = Set([ HKQuantityType.quantityType(forIdentifier: .bodyMass)! ]) self.healthStore?.requestAuthorization(toShare: allTypes, read: allTypes) { (success, error) in var result = "" if success { result = "アクセス許可: \(String(describing: success))" } else { result = "\(String(describing: error?.localizedDescription))" } DispatchQueue.main.async { self.healthKitStatus.setText(result) } } } else { self.healthKitStatus.setText("ヘルスデータ利用不可") } self.items.removeAll() for num in stride(from: 60, through: 80, by: 0.1) { let item = WKPickerItem() item.title = "\(num)" items.append(item) } bodyMassPicker.setItems(items) bodyMassPicker.setSelectedItemIndex(100) } override func willActivate() { // This method is called when watch view controller is about to be visible to user } override func didDeactivate() { // This method is called when watch view controller is no longer visible } @IBAction func selectBodyMass() { guard let bm = Double(self.selectedBodyMass!) else { return } let bodyMassGram = bm * 1000.0 let qty = HKQuantity(unit: .gram(), doubleValue: bodyMassGram) let today = Date() let sample = HKQuantitySample( type: HKSampleType.quantityType(forIdentifier: .bodyMass)!, quantity: qty, start: today, end: today) self.healthStore?.save(sample){ (success, error) in if success { self.healthKitStatus.setText("登録:\(String(describing: self.selectedBodyMass!))") } else { self.healthKitStatus.setText(String(describing: error)) } } } @IBAction func selectBodyMassPicker(_ value: Int) { self.selectedBodyMass = items[value].title } }
登録できた!!
(最初リューズを回した時に発生するイベントで登録してしまったので、やたらデータが登録されてしまった)