I have an HKObserverQuery
setup to fetch steps in the background (enableBackgroundDelivery
method is called in application:didFinishLaunchingWithOptions:
).
The steps are retrieved in the background, but I would also like to store the retrieved steps in a Firebase database. This part is failing though, nothing is stored in Firebase. The method to store the steps does work correctly when the app is in the foreground. Any ideas on how to successfully write data in Firebase while in the background would be appreciated.
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)")
}
}
}
}