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:
@@ -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))
|
||||||
try await WorkoutScheduler.shared.preview(plan)
|
|
||||||
|
// 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)
|
||||||
|
} 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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user