Issue with chart continuously updating

I’m having an issue where my data in my charts are being continuously being re-updated. I believe it is with my onAppear modifier when requesting authorization for HealthKit. I tried to use onDisappear and also trying to the query for the variable but it doesn’t seem to be working in my favor. Upon initial launch of the app the Exercise time data is fine. But as I switch views there is the accumulation. My ChartView is using an @ObservedObject of the viewmodel and I am using the reduce method to calculate the average time ( Text(“Exercise Time Average: (healthStoreVM.exerciseTime.reduce(0, { $0 + $1.exerValue / 7})) mins”)). I’m sorry if the code below is too much or too little. I can add more of it if needed. I’ve posted a video here to display the issue.

ezgif.com-gif-maker


struct MainScreenView: View {
    
    @StateObject var healthStore = HealthStoreViewModel()
   
    var body: some View {
        TabView(selection: $healthStore.selectedTab) {
            
            QuickView(healthStoreVM: healthStore)
                .tabItem {
                    Label("Today", systemImage: "list.bullet.clipboard")
                }
                .tag(1)
            
            StatsView(healthStoreVM: healthStore)
                .tabItem {
                    Label("Statistics", systemImage: "chart.xyaxis.line")
                }
                .tag(2)

            SettingsView(
                stepGoal: $healthStore.stepGoal,
                exerciseDayGoal: $healthStore.exerciseDayGoal, exerciseWeeklyGoal: $healthStore.exerciseWeeklyGoal,
                healthStoreVM: healthStore)
                .tabItem {
                    Label("Settings", systemImage: "slider.horizontal.3")
                }
                .tag(3)
   
        }
    }
}
struct QuickView: View {
  
    @ObservedObject var healthStoreVM: HealthStoreViewModel
    @State private var showInfoSheet = false
   
    
 
    var body: some View {
      
        NavigationStack {
            GeometryReader { geo in
                ScrollView {
                    VStack(spacing: 5) {
                        
                        HStack(spacing: 50) {
                            ExerciseGaugeView(progress: Double(healthStoreVM.currentExTime), minValue: 0.0, maxValue: Double(healthStoreVM.exerciseDayGoal), title: "Today")
                            
                            ExerciseGaugeView(progress: Double(healthStoreVM.currentExTime), minValue: 0.0, maxValue: Double(healthStoreVM.exerciseWeeklyGoal), title: "Weekly")
                        }
                        .padding(.top, 20)
                   
                        VStack (spacing: 5) {
                            StepCountCardView(
                                progress: Double(healthStoreVM.currentStepCount),
                                minValue: 0.0,
                                maxValue: Double(healthStoreVM.stepGoal),
                                title: "\(healthStoreVM.stepCountPercent)%",
                                goalText: healthStoreVM.stepGoal)
                            
                            
                            CurrentSummaryCardView(
                                title: "Resting HR",
                                imageText: "heart.fill",
                                description: healthStoreVM.restHRDescription, color: .red,
                                categoryValue: "\(healthStoreVM.currentRestHR)")
                            
                            CurrentSummaryCardView(
                                title: "Energy Burned",
                                imageText: "flame.fill",
                                description: "",
                                color: .orange,
                                categoryValue: "\(healthStoreVM.currentKcalsBurned)")
                        }
                        .padding(.top, 30)
                    }
                    .onAppear {
                        healthStoreVM.requestUserAuthorization()
                    }
                    .frame(minWidth: geo.size.width * 0.8, maxWidth: .infinity)
                    .padding(.horizontal)
                    .navigationTitle("Health Project App")
                }
            }
        }
    }
}

I’ll try to limit only the exercise variable from my ViewModel

class HealthStoreViewModel: ObservableObject {
    
    var healthStore: HKHealthStore?
    var exerciseTimeQuery: HKStatisticsCollectionQuery?

    @Published var selectedTab = 1
    @Published var exerciseTime: [ExerciseTime] = [ExerciseTime]()
    @Published var exerciseTimeMonth: [ExerciseTime] = [ExerciseTime]()
    @Published var exerciseTime3Months: [ExerciseTime] = [ExerciseTime]()

  var currentExTime: Int {
        exerciseTime.last?.exerValue ?? 0
    }
    

 init(){
        if HKHealthStore.isHealthDataAvailable(){
            healthStore = HKHealthStore()
        } else {
            print("HealthKit is unavailable on this platform")
        }
    }
    

    func requestUserAuthorization() {
    
     
        let exerciseTimeType = HKQuantityType.quantityType(forIdentifier: .appleExerciseTime)!
  
        
        let healthTypes = Set([stepType, restingHeartRateType, exerciseTimeType, caloriesBurnedType])
        
        
        guard let healthStore = self.healthStore else { return }
        
       
        healthStore.requestAuthorization(toShare: [], read: healthTypes) { success, error in

            if success {
                self.calculateStepCountData()
                self.calculateRestingHRData()
                self.calculateSevenDaysExerciseTime()
                self.calculateMonthExerciseTime()
                self.calculate3MonthExerciseTime()
                self.calculateCaloriesBurned()
            }
        }
    }

    func calculateSevenDaysExerciseTime() {
        let exerciseTimeType = HKQuantityType.quantityType(forIdentifier: .appleExerciseTime)!
        let anchorDate = Date.mondayAt12AM()
        let daily = DateComponents(day: 1)
        let oneWeekAgo = Calendar.current.date(byAdding: DateComponents(day: -7), to: Date())!
        let startDate = Calendar.current.date(byAdding: DateComponents(day: -6), to: Date())!
        
        
        let predicate = HKQuery.predicateForSamples(withStart: oneWeekAgo, end: nil, options: .strictStartDate)

        exerciseTimeQuery =  HKStatisticsCollectionQuery(quantityType: exerciseTimeType,
                                                       quantitySamplePredicate: predicate,
                                                       options: .cumulativeSum,
                                                       anchorDate: anchorDate,
                                                       intervalComponents: daily)
    
        exerciseTimeQuery!.initialResultsHandler = {
            exerciseTimeQuery, statisticsCollection, error in
            
            guard let statisticsCollection = statisticsCollection else { return}
            
       
            statisticsCollection.enumerateStatistics(from: startDate, to: Date()) { statistics, stop in
                if let exerciseTimequantity = statistics.sumQuantity() {
                    let exerciseTimedate = statistics.startDate
                    
                    //Exercise Time
                    let exerciseTimevalue = exerciseTimequantity.doubleValue(for: .minute()) 
                    let exTime = ExerciseTime(exerValue: Int(exerciseTimevalue), date: exerciseTimedate)
                    
                    DispatchQueue.main.async {
                        self.exerciseTime.append(exTime)
                    }
                }
            }
        }
        
        
        exerciseTimeQuery!.statisticsUpdateHandler = {
            exerciseTimeQuery, statistics, statisticsCollection, error in
            
            guard let statisticsCollection = statisticsCollection else { return }
            
            statisticsCollection.enumerateStatistics(from: startDate, to: Date()) { statistics, stop in
                if let exerciseTimequantity = statistics.sumQuantity() {
                    let exerciseTimedate = statistics.startDate
                    
            
                    let exerciseTimevalue = exerciseTimequantity.doubleValue(for: .minute())
                    let exTime = ExerciseTime(exerValue: Int(exerciseTimevalue), date: exerciseTimedate)
                    
                    DispatchQueue.main.async {
                        self.exerciseTime.append(exTime)
                    }
                }
            }
        }
        
        
        
        guard let exerciseTimeQuery = self.exerciseTimeQuery else { return }
        self.healthStore?.execute(exerciseTimeQuery)
    }