chore: logs os_log bout-en-bout (watch sendSample + iPhone liveSample) + hook AUTOSIM

Logger unified (capturable via simctl) côté watch (envoi) et iPhone (réception)
pour valider le pont WCSession. Hook AUTOSIM (env var) démarre le mode test au
lancement, pour validation automatisée sur simulateur. Pont prouvé E2E sur sim
pair iPhone+Watch : HR identiques watch->iPhone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sylvain
2026-05-25 20:37:03 +02:00
parent 9f0d90f563
commit 678b5a41d0
3 changed files with 23 additions and 4 deletions

View File

@@ -14,6 +14,9 @@
import Foundation import Foundation
import Capacitor import Capacitor
import WatchConnectivity import WatchConnectivity
import os
private let liveLog = Logger(subsystem: "ch.hypnotruck.coach", category: "live")
@objc(CoachLiveBridgePlugin) @objc(CoachLiveBridgePlugin)
public class CoachLiveBridgePlugin: CAPPlugin, CAPBridgedPlugin { public class CoachLiveBridgePlugin: CAPPlugin, CAPBridgedPlugin {
@@ -46,6 +49,8 @@ public class CoachLiveBridgePlugin: CAPPlugin, CAPBridgedPlugin {
} }
private func emit(_ sample: [String: Any]) { private func emit(_ sample: [String: Any]) {
let hr = (sample["heartRate"] as? Double) ?? -1
liveLog.info("liveSample reçu de la Watch hr=\(hr, privacy: .public)")
CAPLog.print("⚡️ CoachLiveBridge: liveSample reçu de la Watch -> \(sample)") CAPLog.print("⚡️ CoachLiveBridge: liveSample reçu de la Watch -> \(sample)")
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
self?.notifyListeners("liveSample", data: sample) self?.notifyListeners("liveSample", data: sample)

View File

@@ -1,5 +1,8 @@
import Foundation import Foundation
import WatchConnectivity import WatchConnectivity
import os
private let connLog = Logger(subsystem: "ch.hypnotruck.coach.watchkitapp", category: "connectivity")
/// Envoie les samples de séance vers l'iPhone. /// Envoie les samples de séance vers l'iPhone.
/// - `sendMessage` quand l'iPhone est joignable (temps réel) /// - `sendMessage` quand l'iPhone est joignable (temps réel)
@@ -23,6 +26,8 @@ final class ConnectivityManager: NSObject, ObservableObject {
func sendSample(_ payload: [String: Any]) { func sendSample(_ payload: [String: Any]) {
queue.async { queue.async {
let session = WCSession.default let session = WCSession.default
let hr = (payload["heartRate"] as? Double) ?? -1
connLog.info("sendSample activated=\(session.activationState == .activated, privacy: .public) reachable=\(session.isReachable, privacy: .public) hr=\(hr, privacy: .public)")
guard session.activationState == .activated else { guard session.activationState == .activated else {
self.buffer.append(payload) self.buffer.append(payload)
return return

View File

@@ -5,12 +5,21 @@ struct ContentView: View {
@EnvironmentObject private var workout: WorkoutManager @EnvironmentObject private var workout: WorkoutManager
var body: some View { var body: some View {
Group {
if workout.isRunning { if workout.isRunning {
LiveWorkoutView() LiveWorkoutView()
} else { } else {
ActivityPickerView() ActivityPickerView()
} }
} }
.task {
// Déclenchement auto du mode test (validation simulateur) :
// SIMCTL_CHILD_AUTOSIM=1 xcrun simctl launch
if ProcessInfo.processInfo.environment["AUTOSIM"] == "1" {
workout.startSimulation()
}
}
}
} }
struct ActivityPickerView: View { struct ActivityPickerView: View {