12
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SwiftUI×HealthKitでiOSデータ入門(後編)

Last updated at Posted at 2019-12-14

HealthKitデータ取得 & Firebase 編

ここまで SwiftUI のキャチアップをしつつ前編で環境を構築し,中編で HealthKit を利用可能にしました.今回は実際に HealthKit で歩数データを取得します.

HealthKitで歩数データを取得

前回の記事で権限は得られたのでデータの読み出しが可能となっているはずです.次にデータを取得していきます.少しややこしいです.細かいところは順次付け足していくとして,とりいそぎで書き加えたコードだけを載せます.

DataCollection.swift を編集していきます.body より前に以下の変数を定義していきます.

let type = HKObjectType.quantityType(forIdentifier: .stepCount)!  // allTypeとは別にtypeを定義
    var calendar = Calendar.current  // カレンダーを取得

このように書きます(追加したのは下2行).

DataCollection.swift
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  // カレンダーを取得

さらにボタンがタップされた時の処理を以下のように書き換えます.ここでは「昨日から今日まで」に歩いた歩数を取得します.

DataCollection.swift
// ボタンがタップされた時
// もし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) + "歩" // 文字列に変換してデバイスに表示

これで間違いがなければビルドが通り,コンソールに歩数データが表示されるはず.
Screen Shot 2019-12-14 at 20.03.20.png

また,デバイスのボタンをタップすると歩数が表示されるはず.
IMG_8263.PNG

ここまでで,iPhone からデータを取得することに成功しました!

Firebaseへデータを格納

ここからは,先ほど取得したデータをデータベースへ格納します.他のアプリと連携できるように FirebaseFirestore にデータを格納します.当初 Realm を使う予定でしたがハッカソンの戦略上,Firebase へ変更しました.

Firebase (Firestore)

Firebase の環境構築は公式のインストラクションがわかりやすいのでここでは省略します.「Firebase を iOS プロジェクトに追加する」方法をみながら設定をしてください.この設定が済んでいる前提でデータを送るところをやっていきます.

まずは以下の3つのコード

import Firebase
var window: UIWindow?
FirebaseApp.configure()

をAppDelegate.swift に追記します.以下のように書き変えていきます.

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 のボタンがタップされた時の処理を書いた部分に以下の処理を追加します.

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 にも格納されているはずです.
Screen Shot 2019-12-15 at 0.52.36.png

実験で作った余分なコレクションも見えていますが,こんな感じでうまくいきました!

まとめ

ここまでSwift×HealthKitでiOSデータ入門の 前編中編後編 を通してざっくり

  1. Swift (SwiftUI) のキャッチアップとして画面遷移とボタンの実装
  2. HealthKit からのデータの取得
  3. Firebase へのデータの格納

の3つを行いました.iOS開発どころか Xcode や Swift, HealthKit を触るのも初めてだったので説明不足や理解が不十分な点がまだまだあります.このあたりは今後も引き続きキャッチアップとアップデートを行っていこうと考えています.もし気づいた点などあればコメントなどいただけると大変助かります.

以上,SwiftUI×HealthKitでiOSデータ入門 でした.

12
8
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?