[Swift][HealthKit] HealthKit への async なアクセス

     
⌛️ < 1 min.

HealthKit へのアクセスとして async な方法が追加されていたので、その使い方を確認してみます。(実は、iOS15 から追加されていたっぽいです・・・)

環境&対象

以下の環境で動作確認を行なっています。

  • macOS15.1 Sequoia
  • Xcode 16.1 Beta3
  • iOS 18.2 beta
  • Swift 5.9

HealthKit

以前に何回か HealthKit については説明記事を書いています。

[iOS][HealthKit] HealthKit のセットアップ async/await 対応板 [iOS][HealthKit] HealthKit にアクセスする async/await 対応板 [iOS][HealthKit] HealthKit アクセスのための Property List Key まとめ

この記事では、HealthKit へ async に アクセスする方法について確認します。

MEMO

Apple の開発者向けドキュメントには メソッドは、iOS だけでなく macOS にも対応していると記載されています。
ですが、Apple の HIG には、HealthKit は iOS/iPadOS/watchOS でのヘルスケアデータ/フィットネスデータを保存するセントラルリポジトリ と書いてあり、macOS では対応していないと書いてあります。
ということで、本記事では、macOS についての記載は省略(?) しました。

HealthKit への書き込み

以前から、save メソッドは、 async 対応していました。

func save(_ object: HKObject) async throws


参考
save(_:withCompletion:)Apple Developer Documentation

# ドキュメントの中程に、save(_ object:HKObject) async throws が紹介されています。

以下のように、HealthStore のインスタンスの save を使用することで、非同期に保存できます。

func processSomething() async throws {
  let sample = ... // one of HKObject
  try await healthStore.save(sample)
  // process others...
}

HealthKit からの読み込み

iOS15 で、async な読み込みができるようになりました。

HKAsyncQuery を使います。

参考
HKAsyncQueryApple Developer Documentation

上記は、Protocol になっていて、HKSampleQueryDescriptor をはじめとする HK??Descriptor に実装されています。

具体的には、以下のように使用して bodyMass (HKQuantitySample) 要素を取得することができます。

func asyncQueryBodyMass() async throws -> [HKQuantitySample] {
    let typeDescriptor = HKSampleQueryDescriptor(predicates: [.quantitySample(type: HKQuantityType(.bodyMass))],
                                                 sortDescriptors: [])
    return try await typeDescriptor.result(for: healthStore)
}

拍子抜けするくらい簡単ですが、Descriptor が HKQueryDescriptor ではなく、HKSampleQueryDescriptor になっていることに注意が必要です。

# ドキュメントにも記載されていますが、取得数等の設定は、Descriptor で行います。

asyncでない(以前の)読み込み

以前は、HKSampleQuery を読み込む時には、HKQueryDescriptor/ HKSampleQuery を使用して 読み込む必要がありました。

具体的には、HKSampleQuery を HealthStore の execute で実行すると、HKSampleQuery の completionHandler に指定したコードが呼び出されるので、そこでデータを取得するという手順でした。

ざっくり書くと以下のようなコードです。

   let typeDescriptor = HKQueryDescriptor(sampleType: sometype, predicate: nil)
   let query = HKSampleQuery(queryDescriptors: [typeDescriptor], limit: Int(HKObjectQueryNoLimit)) { (query, samples, error) in
        if let error = error {
            // error 処理
            return
        }

        if let samples = samples {
            // samples を保存
        }
        return
     }
  healthStore.execute(query)

なお、複数のタイプを同時に読み込むときには、以前と同様に HKSampleQuery を使用することが必要です。

まとめ

HealthKit への async なアクセスを確認しました。

HealthKit への async なアクセス
  • 保存(save) は、async 対応している
  • 取得(query) は、HKAsyncQuery protocol が async 対応している
  • HKAsyncQuery に conform している HK??Descriptor を使用すると async に取得できる
  • 複数のタイプを同時に読み込みたい時は以前の HKSampleQuery を使用することが必要

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

SwiftUI おすすめ本

SwiftUI を理解するには、以下の本がおすすめです。

SwiftUI ViewMatery

SwiftUI で開発していくときに、ViewやLayoutのための適切なmodifierを探すのが大変です。
英語での説明になってしまいますが、以下の”SwiftUI Views Mastery Bundle”という本がビジュアル的に確認して探せるので、便利です。

英語ではありますが、1ページに コードと画面が並んでいるので、非常にわかりやすいです。

View に適用できる modifier もわかりやすく説明されているので、ビューの理解だけではなく、どのような装飾ができるかも簡単にわかります。

超便利です

SwiftUIViewsMastery

販売元のページは、こちらです。

SwiftUI 徹底入門

# SwiftUI は、毎年大きく改善されていますので、少し古くなってしまいましたが、いまでも 定番本です。

Swift学習におすすめの本

詳解Swift

Swift の学習には、詳解 Swift という書籍が、おすすめです。

著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。

最新版を購入するのがおすすめです。

現時点では、上記の Swift 5 に対応した第5版が最新版です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です