Post

Replies

Boosts

Views

Activity

Reply to Crash on fetching health kit data
I've faced a similar issue while fetching today's steps from HealthKit. I've managed to fix it by creating a predicate using HKQuery.predicateForSamples(withStart:end:options:) and using the .strictStartDate query option. The predicate is then passed to the HKStatisticsCollectionQuery initialiser. Here's an example how to fetch today's current steps and subscribe to updates with this approach: /// Fetches today's total steps and subscribes to all future changes of this value /// - Parameter onUpdate: callback which is called on the initial fetch and every time the value changes in the future func subscribeToStepUpdates(onUpdate: @escaping (Int?) -> Void) { func finishWithResult(_ value: Int?) { DispatchQueue.main.async { onUpdate(value) } } guard let type = HKQuantityType.quantityType(forIdentifier: .stepCount) else { finishWithResult(nil) return } // set the anchor for 0 a.m. let components = DateComponents(calendar: Calendar.current, timeZone: Calendar.current.timeZone, hour: 0, minute: 0, second: 0) guard let anchorDate = Calendar.current.nextDate( after: Date(), matching: components, matchingPolicy: .nextTime, repeatedTimePolicy: .first, direction: .backward ) else { finishWithResult(nil) return } let predicate = HKQuery.predicateForSamples(withStart: Calendar.current.startOfDay(for: Date()), end: nil, options: [.strictStartDate]) let query = HKStatisticsCollectionQuery( quantityType: type, quantitySamplePredicate: predicate, options: .cumulativeSum, anchorDate: anchorDate, intervalComponents: DateComponents(day: 1) ) // initial response query.initialResultsHandler = { [weak self] _, result, error in guard error == nil, let statsCollection = result else { finishWithResult(nil) return } let endDate = Date() let startDate = Calendar.current.startOfDay(for: endDate) var resultCount = 0 statsCollection.enumerateStatistics(from: startDate, to: endDate) { statistics, _ in if let sum = statistics.sumQuantity() { resultCount = Int(sum.doubleValue(for: .count())) } } self?.logger.info("Got today's steps (initial): \(resultCount)") finishWithResult(resultCount) } // subscribe for updates query.statisticsUpdateHandler = { [weak self] _, statistics, _, error in guard error == nil else { return } if let sum = statistics?.sumQuantity() { let steps = Int(sum.doubleValue(for: .count())) self?.logger.info("Got today's steps (update): \(steps)") finishWithResult(steps) } } healthStore?.execute(query) }
Sep ’23