Make Apple Health workout recording watch-only
The phone no longer writes estimated Health workouts: the watch, which runs the live session, is the sole recorder. Replaces WorkoutHealthWriter with a WorkoutHealthDeleter that only removes a legacy phone-estimate workout when its record is deleted here, drops the MET calorie table and the phone's write/read Health scopes, and keeps phoneEstimate decodable for existing documents. Claude-Session: https://claude.ai/code/session_01HJDQQDA9QdP8zByg43H5v3
This commit is contained in:
@@ -9,12 +9,13 @@ import Foundation
|
||||
import HealthKit
|
||||
|
||||
// Bridges the app's HealthKit-free domain types to HealthKit, and centralizes the
|
||||
// authorization type sets so the watch (which records the session) and the phone
|
||||
// (which writes an estimated workout when no watch ran) request consistent scopes.
|
||||
// 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 a saved workout, so it lands in the
|
||||
/// right Apple Health / Fitness category and credits the rings appropriately.
|
||||
/// 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
|
||||
@@ -52,16 +53,10 @@ enum WorkoutHealthAuthorization {
|
||||
HKCharacteristicType(.dateOfBirth), // → max HR for zone tracking
|
||||
]
|
||||
|
||||
/// Phone: writes an estimated workout when no watch session ran; reads body
|
||||
/// measurements to size the calorie estimate (and HR to display watch data).
|
||||
/// 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<HKSampleType> = [
|
||||
.workoutType(),
|
||||
HKQuantityType(.activeEnergyBurned),
|
||||
]
|
||||
static let phoneRead: Set<HKObjectType> = [
|
||||
HKQuantityType(.bodyMass),
|
||||
HKQuantityType(.heartRate),
|
||||
HKCharacteristicType(.dateOfBirth),
|
||||
HKCharacteristicType(.biologicalSex),
|
||||
]
|
||||
}
|
||||
|
||||
@@ -35,9 +35,8 @@ enum LoadType: Int, CaseIterable, Codable, Sendable {
|
||||
}
|
||||
}
|
||||
|
||||
/// The kind of training a split represents — used to tag the Apple Health workout
|
||||
/// so it lands in the right category (and credits the rings correctly), and to pick
|
||||
/// a MET value when the phone has to estimate calories without watch sensor data.
|
||||
/// The kind of training a split represents — used to tag the watch's Apple Health
|
||||
/// workout so it lands in the right category (and credits the rings correctly).
|
||||
/// Persisted as its raw `Int` on `SplitDocument`; the `HKWorkoutActivityType`
|
||||
/// mapping lives in `Shared/HealthKit/HealthKitMapping.swift` to keep this enum
|
||||
/// HealthKit-free.
|
||||
@@ -70,23 +69,13 @@ enum WorkoutActivityType: Int, CaseIterable, Codable, Sendable {
|
||||
case .cycling: "figure.outdoor.cycle"
|
||||
}
|
||||
}
|
||||
|
||||
/// Metabolic-equivalent value used only for the phone-side calorie estimate
|
||||
/// (`kcal ≈ MET × bodyweightKg × hours`) when no watch metrics are available.
|
||||
var met: Double {
|
||||
switch self {
|
||||
case .traditionalStrength: 5.0
|
||||
case .functionalStrength: 4.0
|
||||
case .hiit: 8.0
|
||||
case .coreTraining: 4.0
|
||||
case .cardio: 7.0
|
||||
case .cycling: 7.5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Where a workout's health metrics came from: real watch sensors, or a phone-side
|
||||
/// estimate written when no watch session ran. Persisted in `WorkoutMetrics`.
|
||||
/// Where a workout's health metrics came from: real watch sensors, or — for records
|
||||
/// written by app versions up to 2.x — a phone-side MET estimate made when no watch
|
||||
/// session ran. The phone no longer writes estimates (recording is watch-only), but
|
||||
/// `phoneEstimate` is retained so legacy documents on disk still decode. Persisted in
|
||||
/// `WorkoutMetrics`.
|
||||
enum MetricSource: String, Codable, Sendable {
|
||||
case watch
|
||||
case phoneEstimate
|
||||
|
||||
Reference in New Issue
Block a user