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:
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -5,10 +5,19 @@ struct ContentView: View {
|
|||||||
@EnvironmentObject private var workout: WorkoutManager
|
@EnvironmentObject private var workout: WorkoutManager
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
if workout.isRunning {
|
Group {
|
||||||
LiveWorkoutView()
|
if workout.isRunning {
|
||||||
} else {
|
LiveWorkoutView()
|
||||||
ActivityPickerView()
|
} else {
|
||||||
|
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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user