Healthkitを使って歩数データを取得して監視する

Healthkitで歩数データを取得する方法は調べると結構出てくるが、歩数データが更新されたのを監視する方法があまりなかったのでメモ。

歩数データを1日単位で数年分取得するには、下記のようにHKStatisticsCollectionQueryを使う。

ちなみに、anchorDateはデータ取得開始日と同じ2007年1月1日(start)にしている。

let type = HKQuantityType.quantityType(forIdentifier: .stepCount)!
let interval = DateComponents(day:1)
let query = HKStatisticsCollectionQuery(quantityType: type, quantitySamplePredicate: nil, options: .cumulativeSum, anchorDate: start, intervalComponents: interval)

初回起動の時には以下のハンドラーが呼ばれる。

ここでは歩数を1日単位で辞書に登録しておくことにした。

        query.initialResultsHandler = { _, result, error in
            guard let result = result else { return }
            
            let end = Date()
            
            result.enumerateStatistics(from: start, to: end, with: { stats, _ in
                
                if let step = stats.sumQuantity()?.doubleValue(for: HKUnit.count()){
                    let day = stats.startDate.DateToStringFormatter(format: "yyyy-MM-dd")
                    
                    DispatchQueue.main.async {
                        self.StepData[day] = Int(step)
                    }
                }
                
            })
            
            DispatchQueue.main.async {
                self.isStepLoading = false
                self.lastupdate = end
            }
        }

2007年1月1日〜現在、までの歩数が1日単位で取得できた。

その後に更新された場合は更新用のハンドラがあるのでこれを使えば良い。

実行したらアップデート日時を更新している。

query.statisticsUpdateHandler = {_,_,result,_ in
            guard let result = result else { return }
            
            let end = Date()
            
            if let last = self.lastupdate{
                
                result.enumerateStatistics(from: last, to: end, with: { stats, _ in
                    if let step = stats.sumQuantity()?.doubleValue(for: HKUnit.count()){
                        let day = stats.startDate.DateToStringFormatter(format: "yyyy-MM-dd")
                        
                        DispatchQueue.main.async {
                            self.StepData[day] = Int(step)
                            self.lastupdate = end
                        }
                    }
                })
            }
            
        }

最後にクエリーを実行するのをお忘れなく。

healthStore.execute(query)

😀

ABOUTこの記事をかいた人

個人アプリ開発者。Python、Swift、Unityのことを発信します。月間2.5万PVブログ運営。 Twitter:@yamagablog