I am having points with my updateHandler when retrieving train minutes. Beforehand, my train minutes would replace and firstly of a brand new day would reset again to zero. Now, my train minutes nonetheless shows the worth from the day gone by and doesn’t reset again to zero for a brand new day. Evidently I’ve to truly get some train minutes for it to truly replace. I’ve had no points till just lately and I have never modified my code because the starting. I observed this problem when taking a look at my graphs of simply retrieving the previous 7 days of knowledge. Step rely would replace to the brand new day however not my train minute graph. I’ve tried setting break factors and seeing if there’s points with the dates however there is not when retrieving for train time. I’ve additionally in contrast it to the logic for step rely knowledge and each are comparable. I’ve my ViewModel and consider that I exploit to show the train minutes. I will additionally connect photos of my graphs to indicate you.
class HealthStoreViewModel: ObservableObject {
var healthStore: HKHealthStore?
let exerciseTimeType = HKQuantityType.quantityType(forIdentifier: .appleExerciseTime)!
var exerciseTimeQuery: HKStatisticsCollectionQuery?
@Revealed var exerciseTime: [ExerciseTime] = [ExerciseTime]()
//Computed properties
var currentExTime: Int {
exerciseTime.final?.exerValue ?? 0
}
//That is for the week beginning Sunday - Saturday
var weeklyExTime: Int {
exerciseTime.cut back(0) { $0 + $1.exerValue }
}
let anchorDate = Date.sundayAt12AM()
let day by day = DateComponents(day: 1)
init(){
if HKHealthStore.isHealthDataAvailable(){
healthStore = HKHealthStore()
showAllExerciseData()
} else {
print("HealthKit is unavailable on this platform")
}
}
func requestUserAuthorization() {
let healthTypes = Set([stepType, restingHeartRateType, hrvType, exerciseTimeType, caloriesBurnedType, workoutType])
guard let healthStore = self.healthStore else {
return
}
healthStore.requestAuthorization(toShare: [], learn: healthTypes) { success, error in
if success {
self.showAllExerciseData()
}
}
}
func showAllExerciseData() {
self.calculateSevenDaysExerciseTime()
//There's extra strategies to retrieve different well being stats, however solely displaying train time right here.
}
func calculateSevenDaysExerciseTime() {
let startDate = Calendar.present.dateInterval(of: .weekOfYear, for: Date())?.begin ?? Date()
let predicate = HKQuery.predicateForSamples(withStart: startDate, finish: nil, choices: .strictStartDate)
exerciseTimeQuery = HKStatisticsCollectionQuery(quantityType: exerciseTimeType,
quantitySamplePredicate: predicate,
choices: .cumulativeSum,
anchorDate: anchorDate,
intervalComponents: day by day)
exerciseTimeQuery!.initialResultsHandler = {
exerciseTimeQuery, statisticsCollection, error in
//Deal with errors right here
if let error = error as? HKError {
swap (error.code) {
case .errorHealthDataUnavailable:
return
case .errorNoData:
return
default:
return
}
}
guard let statisticsCollection = statisticsCollection else { return}
//Calculating train time
statisticsCollection.enumerateStatistics(from: startDate, to: self.date) { statistics, cease in
if let exerciseTimequantity = statistics.sumQuantity() {
let exerciseTimedate = statistics.startDate
//Train Time
let exerciseTimevalue = exerciseTimequantity.doubleValue(for: .minute())
let exTime = ExerciseTime(exerValue: Int(exerciseTimevalue), date: exerciseTimedate)
DispatchQueue.foremost.async {
self.exerciseTime.append(exTime)
}
}
}
}
exerciseTimeQuery!.statisticsUpdateHandler = {
exerciseTimeQuery, statistics, statisticsCollection, error in
//Deal with errors right here
if let error = error as? HKError {
swap (error.code) {
case .errorHealthDataUnavailable:
return
case .errorNoData:
return
default:
return
}
}
guard let statisticsCollection = statisticsCollection else { return }
statisticsCollection.enumerateStatistics(from: startDate, to: self.date) { statistics, cease in
if let exerciseTimequantity = statistics.sumQuantity() {
let exerciseTimedate = statistics.startDate
//Train Time
let exerciseTimevalue = exerciseTimequantity.doubleValue(for: .minute())
let exTime = ExerciseTime(exerValue: Int(exerciseTimevalue), date: exerciseTimedate)
DispatchQueue.foremost.async {
self.exerciseTime.append(exTime)
}
}
}
}
guard let exerciseTimeQuery = self.exerciseTimeQuery else { return }
self.healthStore?.execute(exerciseTimeQuery)
}
}
My view to show the Train minutes
HStack(spacing: 50) {
ExerciseGaugeView(progress: Double(healthStoreVM.currentExTime), minValue: 0.0, maxValue: Double(healthStoreVM.exerciseDayGoal), title: "At the moment", dateText: Constants.todayDateString)
ExerciseGaugeView(progress: Double(healthStoreVM.weeklyExTime),
minValue: 0.0,
maxValue: Double(healthStoreVM.exerciseWeeklyGoal),
title: "Weekly Complete", dateText: Constants.currentWeekDatesString)
}
See how step rely is show April third knowledge and Train minutes is not up to date but? The 73 train minutes ought to be again to zero.