feat(workoutkit): whitelist activities + isInspectable WKWebView
Backlog #1 — WKWebView debugging via Safari Web Inspector : - MainViewController.swift : webView?.isInspectable = true (iOS 16.4+) - Permet de débugger l'app TestFlight depuis Safari Web Inspector Mac (menu Développement → iPhone → coach.hypnotruck.ch). Sans ça, la WebView ne remonte pas dans la liste des cibles inspectables. Backlog #2 — Whitelist défensive activities CustomWorkout : - Nouvelle fonction isSafeForCustomWorkout(HKWorkoutActivityType) -> Bool - Whitelist : running, cycling, swimming, walking, hiking, rowing, skatingSports, paddleSports (confirmées doc Apple WWDC23+24) + functionalStrengthTraining, traditionalStrengthTraining (confirmées empiriquement le 2026-05-18 build 15). - Pour toute activity hors whitelist (yoga, pilates, hiit, crossTraining, coreTraining, etc.) : fallback automatique sur .running avec NSLog warning. Évite les precondition crashes CustomWorkout.init pour activities non testées. - Retour JS enrichi : { sent, activityUsed (rawValue), activityFallback (bool) } pour permettre au web d'afficher un avertissement si fallback. Bump version requis côté Mac avant rebuild TestFlight.
This commit is contained in:
@@ -98,7 +98,19 @@ public class CoachWorkoutKitPlugin: CAPPlugin, CAPBridgedPlugin {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let activity = workoutActivity(from: activityStr)
|
let requestedActivity = workoutActivity(from: activityStr)
|
||||||
|
// Whitelist défensive — CustomWorkout.init fait des asserts internes
|
||||||
|
// (precondition failure non catchable, crash dur) pour les activities
|
||||||
|
// non supportées. La doc Apple confirme : .running, .cycling toujours,
|
||||||
|
// .swimming/.rowing/.skating depuis watchOS 11 (WWDC24). Empirique
|
||||||
|
// (testé 2026-05-18 build 15) : .functionalStrengthTraining marche.
|
||||||
|
// Pour tout le reste : fallback .running pour éviter crash.
|
||||||
|
let activity = isSafeForCustomWorkout(requestedActivity)
|
||||||
|
? requestedActivity
|
||||||
|
: .running
|
||||||
|
if activity != requestedActivity {
|
||||||
|
NSLog("[CoachWorkoutKit] Activity rawValue=%lu not whitelisted for CustomWorkout, falling back to .running", requestedActivity.rawValue)
|
||||||
|
}
|
||||||
|
|
||||||
Task {
|
Task {
|
||||||
do {
|
do {
|
||||||
@@ -110,13 +122,34 @@ public class CoachWorkoutKitPlugin: CAPPlugin, CAPBridgedPlugin {
|
|||||||
repeats: repeats,
|
repeats: repeats,
|
||||||
cooldownMin: cooldownMin
|
cooldownMin: cooldownMin
|
||||||
)
|
)
|
||||||
call.resolve(["sent": true])
|
call.resolve([
|
||||||
|
"sent": true,
|
||||||
|
"activityUsed": Int(activity.rawValue),
|
||||||
|
"activityFallback": activity != requestedActivity,
|
||||||
|
])
|
||||||
} catch {
|
} catch {
|
||||||
call.reject("Failed to send workout: \(error.localizedDescription)")
|
call.reject("Failed to send workout: \(error.localizedDescription)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Whitelist des HKWorkoutActivityType compatibles avec CustomWorkout.
|
||||||
|
// Mettre à jour dès qu'une nouvelle activity est testée empiriquement
|
||||||
|
// sans crash sur watchOS / iOS courants.
|
||||||
|
private func isSafeForCustomWorkout(_ activity: HKWorkoutActivityType) -> Bool {
|
||||||
|
switch activity {
|
||||||
|
// Confirmé doc Apple WWDC23+24
|
||||||
|
case .running, .cycling, .swimming, .walking, .hiking,
|
||||||
|
.rowing, .skatingSports, .paddleSports:
|
||||||
|
return true
|
||||||
|
// Confirmé empiriquement 2026-05-18 (build 15)
|
||||||
|
case .functionalStrengthTraining, .traditionalStrengthTraining:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func workoutActivity(from str: String) -> HKWorkoutActivityType {
|
private func workoutActivity(from str: String) -> HKWorkoutActivityType {
|
||||||
switch str.lowercased() {
|
switch str.lowercased() {
|
||||||
// Cardio outdoor
|
// Cardio outdoor
|
||||||
|
|||||||
@@ -27,5 +27,13 @@ class MainViewController: CAPBridgeViewController {
|
|||||||
webView?.isOpaque = false
|
webView?.isOpaque = false
|
||||||
webView?.backgroundColor = .black
|
webView?.backgroundColor = .black
|
||||||
webView?.scrollView.backgroundColor = .black
|
webView?.scrollView.backgroundColor = .black
|
||||||
|
|
||||||
|
// Permet l'inspection de la WKWebView depuis Safari Web Inspector
|
||||||
|
// (Mac : menu Développement → iPhone → coach.hypnotruck.ch) y compris
|
||||||
|
// pour les builds TestFlight. iOS 16.4+ requis. Sans ça, l'app
|
||||||
|
// n'apparaît pas dans la liste des cibles inspectables.
|
||||||
|
if #available(iOS 16.4, *) {
|
||||||
|
webView?.isInspectable = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user