feat(watchos): mode Test (FC simulée) — valide le flux sans HealthKit
Bouton "Test (FC simulée)" qui envoie des samples synthétiques (FC ~110-150, calories, distance, durée) via WCSession toutes les 2s, sans démarrer de séance HealthKit. Permet de valider watch -> iPhone -> /live indépendamment de l'autorisation Santé (bloquée par un sous-système Santé coincé sur la Watch). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,7 @@ final class WorkoutManager: NSObject, ObservableObject {
|
||||
|
||||
private var lastSentAt = Date.distantPast
|
||||
private let sendInterval: TimeInterval = 2
|
||||
private var simTask: Task<Void, Never>?
|
||||
|
||||
private override init() { super.init() }
|
||||
|
||||
@@ -86,7 +87,47 @@ final class WorkoutManager: NSObject, ObservableObject {
|
||||
|
||||
func pause() { session?.pause() }
|
||||
func resume() { session?.resume() }
|
||||
func end() { session?.end() }
|
||||
|
||||
func end() {
|
||||
if let simTask {
|
||||
simTask.cancel()
|
||||
self.simTask = nil
|
||||
isRunning = false
|
||||
statusMessage = nil
|
||||
} else {
|
||||
session?.end()
|
||||
}
|
||||
}
|
||||
|
||||
/// Mode test : FC simulée, sans HealthKit, pour valider le flux watch -> iPhone -> /live.
|
||||
func startSimulation() {
|
||||
guard !isRunning else { return }
|
||||
isRunning = true
|
||||
statusMessage = "Mode test — FC simulée"
|
||||
let startedAt = Date()
|
||||
simTask = Task { [weak self] in
|
||||
while !Task.isCancelled {
|
||||
guard let self else { return }
|
||||
let elapsed = Date().timeIntervalSince(startedAt)
|
||||
let hr = 110 + 40 * abs(sin(elapsed / 30))
|
||||
let kcal = elapsed / 6
|
||||
let dist = elapsed * 2.6
|
||||
self.heartRate = hr
|
||||
self.activeEnergyKcal = kcal
|
||||
self.distanceMeters = dist
|
||||
self.elapsedSec = elapsed
|
||||
ConnectivityManager.shared.sendSample([
|
||||
"heartRate": hr,
|
||||
"activeEnergyKcal": kcal,
|
||||
"distanceMeters": dist,
|
||||
"elapsedSec": elapsed,
|
||||
"ts": Date().timeIntervalSince1970,
|
||||
"sim": true
|
||||
])
|
||||
try? await Task.sleep(nanoseconds: 2_000_000_000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Appelé sur le main depuis le callback de collecte (hors-main).
|
||||
private func ingest(hr: Double?, kcal: Double?, dist: Double?, elapsed: TimeInterval) {
|
||||
|
||||
Reference in New Issue
Block a user