// // HealthKitMapping.swift // Workouts (Shared) // // Copyright 2025 Rouslan Zenetl. All Rights Reserved. // import Foundation import HealthKit // Bridges the app's HealthKit-free domain types to HealthKit, and centralizes the // authorization type sets. The watch records the live session (shares the workout + // energy, reads HR back); the phone only ever deletes a legacy phone-estimate workout // it previously authored, so it needs nothing but workout-share. extension WorkoutActivityType { /// The HealthKit activity type used to tag the watch's saved workout, so it lands /// in the right Apple Health / Fitness category and credits the rings appropriately. var hkActivityType: HKWorkoutActivityType { switch self { case .traditionalStrength: .traditionalStrengthTraining case .functionalStrength: .functionalStrengthTraining case .hiit: .highIntensityIntervalTraining case .coreTraining: .coreTraining case .cardio: .mixedCardio case .cycling: .cycling } } } /// Σ sets×reps×weight across weighted logs — the app-native "how much work" number. /// Computed in the stored weight unit (display-only units never change the value). enum WorkoutVolume { static func total(_ logs: [WorkoutLogDocument]) -> Double { logs.reduce(0) { sum, log in guard LoadType(rawValue: log.loadType) == .weight else { return sum } return sum + Double(log.sets * log.reps * log.weight) } } } /// The HealthKit scopes each side requests. Kept here so the share/read sets stay in /// sync with what the writers actually use. enum WorkoutHealthAuthorization { /// Watch: records a live session (writes the workout + energy, reads HR/energy back). static let watchShare: Set = [ .workoutType(), HKQuantityType(.activeEnergyBurned), ] static let watchRead: Set = [ HKQuantityType(.heartRate), HKQuantityType(.activeEnergyBurned), HKCharacteristicType(.dateOfBirth), // → max HR for zone tracking ] /// Phone: shares only the workout type, the minimum HealthKit requires to delete a /// legacy phone-estimate `HKWorkout` this app authored. The phone reads nothing and /// no longer writes any workouts of its own (recording is watch-only). static let phoneShare: Set = [ .workoutType(), ] }