fix CoachWorkoutKit Swift : API WorkoutKit corrigée

Compile errors :
- WorkoutAlertEnumeration n'existe pas → c'est WorkoutAlert (et il faut
  passer l'alert via WorkoutStep.alert, pas en param d'IntervalStep)
- IntervalStep init est .init(_ purpose:, step: WorkoutStep) — pas de goal
  ni alert direct, faut wrapper dans WorkoutStep d'abord
- WorkoutScheduler.shared.preview(plan) ajouté en iOS 17.4+ → wrap dans
  if #available(17.4) avec fallback schedule() pour 17.0-17.3

Ajouts :
- requestAuthorization() avant preview/schedule (idempotent si déjà accordée)
- HeartRateZoneAlert appliqué sur work + rest steps via .alert (style mutable)
This commit is contained in:
Sylvain Bettinelli
2026-05-08 09:40:34 +00:00
parent 2d3e149c0a
commit cfa6a8bb52

View File

@@ -14,12 +14,12 @@
// repeats: 6, // repeats: 6,
// cooldownMin: 10, // cooldownMin: 10,
// }) // })
// { sent: true } si l'user a tapé "Ajouter aux workouts" dans la sheet // { sent: true } si la sheet a été présentée et user a tapé Ajouter
// reject avec error string sinon // reject avec error string sinon
// //
// L'app présente une sheet système iOS qui demande à l'user de confirmer // Sur iOS 17.4+ : utilise WorkoutScheduler.shared.preview(plan) qui ouvre
// l'ajout du workout au Watch. Le workout devient alors disponible dans // la sheet système iOS 'Ajouter aux workouts'.
// Apple Watch Exercice Workouts personnalisés [displayName]. // Sur iOS 17.0-17.3 (rare) : fallback schedule() qui ajoute direct.
import Foundation import Foundation
import Capacitor import Capacitor
@@ -103,50 +103,59 @@ public class CoachWorkoutKitPlugin: CAPPlugin {
repeats: Int, repeats: Int,
cooldownMin: Double cooldownMin: Double
) async throws { ) async throws {
// 1. Warmup step (1 fois)
// 1. Warmup un WorkoutStep avec un goal time
let warmupStep = WorkoutStep(goal: .time(warmupMin * 60, .seconds)) let warmupStep = WorkoutStep(goal: .time(warmupMin * 60, .seconds))
// 2. Work + Rest interval block (répété N fois) // 2. Work step wrapped dans un IntervalStep avec purpose .work
var workAlerts: [any WorkoutAlertEnumeration] = [] var workWorkoutStep = WorkoutStep(goal: .time(workMin * 60, .seconds))
if let zone = workHrZone { if let zone = workHrZone {
workAlerts.append(HeartRateZoneAlert(zone: zone)) workWorkoutStep.alert = HeartRateZoneAlert(zone: zone)
} }
let workStep = IntervalStep( let workInterval = IntervalStep(.work, step: workWorkoutStep)
.work,
goal: .time(workMin * 60, .seconds),
alert: workAlerts.first as? (any WorkoutAlertEnumeration)
)
var restAlerts: [any WorkoutAlertEnumeration] = [] // 3. Rest step IntervalStep purpose .recovery
var restWorkoutStep = WorkoutStep(goal: .time(restMin * 60, .seconds))
if let zone = restHrZone { if let zone = restHrZone {
restAlerts.append(HeartRateZoneAlert(zone: zone)) restWorkoutStep.alert = HeartRateZoneAlert(zone: zone)
} }
let restStep = IntervalStep( let restInterval = IntervalStep(.recovery, step: restWorkoutStep)
.recovery,
goal: .time(restMin * 60, .seconds),
alert: restAlerts.first as? (any WorkoutAlertEnumeration)
)
let intervalBlock = IntervalBlock( // 4. Block répété N fois
steps: [workStep, restStep], let block = IntervalBlock(steps: [workInterval, restInterval], iterations: repeats)
iterations: repeats
)
// 3. Cooldown step // 5. Cooldown
let cooldownStep = WorkoutStep(goal: .time(cooldownMin * 60, .seconds)) let cooldownStep = WorkoutStep(goal: .time(cooldownMin * 60, .seconds))
// 4. Custom workout // 6. CustomWorkout
let custom = CustomWorkout( let custom = CustomWorkout(
activity: activity, activity: activity,
location: .outdoor, location: .outdoor,
displayName: displayName, displayName: displayName,
warmup: warmupStep, warmup: warmupStep,
blocks: [intervalBlock], blocks: [block],
cooldown: cooldownStep cooldown: cooldownStep
) )
// 5. Plan + preview (présente la sheet système "Ajouter à mes workouts") // 7. Plan
let plan = WorkoutPlan(.custom(custom)) let plan = WorkoutPlan(.custom(custom))
// 8. Request authorization si pas déjà accordée
let authState = await WorkoutScheduler.shared.authorizationState
if authState != .authorized {
_ = try await WorkoutScheduler.shared.requestAuthorization()
}
// 9. Présenter la sheet système (iOS 17.4+) ou scheduler direct (17.0-17.3)
if #available(iOS 17.4, *) {
try await WorkoutScheduler.shared.preview(plan) try await WorkoutScheduler.shared.preview(plan)
} else {
// Fallback : schedule "now" pour rendre dispo sur Watch
let now = Calendar.current.dateComponents(
[.year, .month, .day, .hour, .minute],
from: Date()
)
_ = try await WorkoutScheduler.shared.schedule(plan, at: now)
}
} }
} }