HealthKitデータ取得 & Firebase 編
ここまで SwiftUI のキャチアップをしつつ前編で環境を構築し,中編で HealthKit を利用可能にしました.今回は実際に HealthKit で歩数データを取得します.
HealthKitで歩数データを取得
前回の記事で権限は得られたのでデータの読み出しが可能となっているはずです.次にデータを取得していきます.少しややこしいです.細かいところは順次付け足していくとして,とりいそぎで書き加えたコードだけを載せます.
DataCollection.swift を編集していきます.body より前に以下の変数を定義していきます.
let type = HKObjectType.quantityType(forIdentifier: .stepCount)! // allTypeとは別にtypeを定義
var calendar = Calendar.current // カレンダーを取得
このように書きます(追加したのは下2行).
struct DataCollection: View {
// @Stateを使ってUIの状態と同期をとる
@State var labelText = "Tap Here"
@State var flag = false
let healthStore = HKHealthStore() // HealthKitのデータを格納するHealthStoreを定義
// アクセス許可が欲しいデータタイプを指定
let allTypes = Set([HKObjectType.quantityType(forIdentifier: .stepCount)!]) //今回は歩数のみ
// 以下を追加
let type = HKObjectType.quantityType(forIdentifier: .stepCount)! // allTypeとは別にtypeを定義
var calendar = Calendar.current // カレンダーを取得
さらにボタンがタップされた時の処理を以下のように書き換えます.ここでは「昨日から今日まで」に歩いた歩数を取得します.
// ボタンがタップされた時
// もしHealthKitが利用可能なら
if HKHealthStore.isHealthDataAvailable() {
self.labelText = "HealthKit Available"
self.healthStore.requestAuthorization(toShare: nil, read: self.allTypes) { (success, error) in}
// 以下を追加
let date = Date() // 今日の日付を取得
let yesterday = self.calendar.date(byAdding: .day, value: -1, to: date) // "昨日"は上で定義したカレンダーを使って計算する
// 取得するデータの開始(きのう)と終わり(きょう)を入れる
let predicate = HKQuery.predicateForSamples(withStart: yesterday, end: date)
var step = 0.0 // 結果を格納するための変数
// クエリを作る
let query = HKStatisticsQuery(quantityType: self.type, quantitySamplePredicate: predicate, options:.cumulativeSum){query, result, error in
let query_result = result?.sumQuantity() as Any
step = (query_result as AnyObject).doubleValue(for: HKUnit.count()) // HKQuantity型をdoubleに変換
print(step) // コンソールに出力
self.labelText = String(step) + "歩" // 文字列に変換してデバイスに表示
これで間違いがなければビルドが通り,コンソールに歩数データが表示されるはず.
ここまでで,iPhone からデータを取得することに成功しました!
Firebaseへデータを格納
ここからは,先ほど取得したデータをデータベースへ格納します.他のアプリと連携できるように Firebase の Firestore にデータを格納します.当初 Realm を使う予定でしたがハッカソンの戦略上,Firebase へ変更しました.
Firebase (Firestore)
Firebase の環境構築は公式のインストラクションがわかりやすいのでここでは省略します.「Firebase を iOS プロジェクトに追加する」方法をみながら設定をしてください.この設定が済んでいる前提でデータを送るところをやっていきます.
まずは以下の3つのコード
import Firebase
var window: UIWindow?
FirebaseApp.configure()
をAppDelegate.swift に追記します.以下のように書き変えていきます.
import UIKit
import Firebase // 追加した行
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow? // 追加した行
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
// Firebase
FirebaseApp.configure() // 追加した行
return true
}
そして DataCollection.swift のボタンがタップされた時の処理を書いた部分に以下の処理を追加します.
<略>
// クエリを作る
let query = HKStatisticsQuery(quantityType: self.type, quantitySamplePredicate: predicate, options:.cumulativeSum){
query, result, error in
let query_result = result?.sumQuantity() as Any
step = (query_result as AnyObject).doubleValue(for: HKUnit.count()) // HKQuantity型をdoubleに変換
print(step) // コンソールに出力
self.labelText = String(step) + "歩" // デバイスに表示
// ここからが追加したFirebaseの処理
let db = Firestore.firestore()
var ref: DocumentReference? = nil
ref = db.collection("Health").addDocument(data: [
"歩数": step
]) { err in
if let err = err {
print("Error adding document: \(err)")
} else {
print("Document added with ID: \(ref!.documentID)")
}
}
}
self.healthStore.execute(query)
}else{
<略>
これで問題なければ,ボタンを押すたびにデータが FireStore にも格納されているはずです.
実験で作った余分なコレクションも見えていますが,こんな感じでうまくいきました!
まとめ
ここまでSwift×HealthKitでiOSデータ入門の 前編,中編,後編 を通してざっくり
- Swift (SwiftUI) のキャッチアップとして画面遷移とボタンの実装
- HealthKit からのデータの取得
- Firebase へのデータの格納
の3つを行いました.iOS開発どころか Xcode や Swift, HealthKit を触るのも初めてだったので説明不足や理解が不十分な点がまだまだあります.このあたりは今後も引き続きキャッチアップとアップデートを行っていこうと考えています.もし気づいた点などあればコメントなどいただけると大変助かります.
以上,SwiftUI×HealthKitでiOSデータ入門 でした.