HKObserverQuery
の設定で、バックグラウンドでステップを取得します(メソッドはapplication:didFinishLaunchingWithOptions:
で呼び出されます)。HealthKitのバックグラウンドデリバリでステップを取得した後、バックグラウンドでFirebaseにデータを書き込む
ステップはバックグラウンドで取得されますが、取得したステップをFirebaseデータベースに保存することもできます。この部分は失敗しますが、Firebaseには何も保存されていません。アプリをフォアグラウンドにすると、ステップを保存するメソッドが正しく動作します。バックグラウンドでFirebaseにデータを書き込む方法に関するアイデアは高く評価されます。
class HealthKitManager {
static let shared = HealthKitManager()
private let healthStore = HKHealthStore()
private let stepsQuantityType = HKQuantityType.quantityType(forIdentifier: .stepCount)!
private init() {
}
func getTodaysStepCount(completion: @escaping (Double) -> Void) {
let now = Date()
let startOfDay = Calendar.current.startOfDay(for: now)
let predicate = HKQuery.predicateForSamples(withStart: startOfDay, end: now, options: .strictStartDate)
let query = HKStatisticsQuery(quantityType: stepsQuantityType, quantitySamplePredicate: predicate, options: .cumulativeSum) { (_, result, error) in
var resultCount = 0.0
guard let result = result else {
log.error("Failed to fetch steps = \(error?.localizedDescription ?? "N/A")")
completion(resultCount)
return
}
if let sum = result.sumQuantity() {
resultCount = sum.doubleValue(for: HKUnit.count())
}
DispatchQueue.main.async {
completion(resultCount)
}
}
healthStore.execute(query)
}
func enableBackgroundDelivery() {
let query = HKObserverQuery(sampleType: stepsQuantityType, predicate: nil) { [weak self] (query, completionHandler, error) in
if let error = error {
log.error("Observer query failed = \(error.localizedDescription)")
return
}
self?.getTodaysStepCount(completion: { steps in
// Store steps using Firebase:
StepsManager.shared.updateUserSteps(steps)
completionHandler()
})
}
healthStore.execute(query)
healthStore.enableBackgroundDelivery(for: stepsQuantityType, frequency: .hourly) { (success, error) in
log.debug("Background delivery of steps. Success = \(success)")
if let error = error {
log.error("Background delivery of steps failed = \(error.localizedDescription)")
}
}
}
}