Files
coach-ios/ios/App/CoachLiveActivity/CoachLiveActivityAttributes.swift
Sylvain a5795bf83f feat(live): Live Activity / Dynamic Island (WidgetKit extension iOS 16.2+/17+)
Nouvelle target "CoachLiveActivity" (Widget Extension, bundle
ch.hypnotruck.coach.LiveActivity, iOS 17.0) embarquée dans App via copy phase
"Embed App Extensions" (dstSubfolderSpec=13). API ActivityKit + WidgetKit
vérifiées sur SDK iOS 26.5 swiftinterface (Activity.request(content:),
ActivityConfiguration, DynamicIsland(expanded:compactLeading:trailing:minimal:)).

Architecture :
- CoachLiveActivityAttributes (modèle partagé App ↔ extension)
- CoachLiveActivityWidget (Lock Screen + Dynamic Island UI)
- CoachLiveActivityBundle (@main WidgetBundle)
- LiveActivityManager (App side, wrap Activity.request/update/end)
- LiveStore hook : start sur 1er sample, update à chaque ingest, end après
  60s "lost". Tout guardé @available(iOS 16.2, *) pour préserver deployment iOS 15.
- Info.plist App : NSSupportsLiveActivities = YES.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 19:51:57 +02:00

24 lines
903 B
Swift

// CoachLiveActivityAttributes.swift
// Modèle partagé App Widget Extension (membre des 2 targets).
// Définit ce que la Live Activity / Dynamic Island affiche.
import ActivityKit
import Foundation
@available(iOS 16.2, *)
struct CoachLiveActivityAttributes: ActivityAttributes {
/// Données dynamiques (mises à jour à chaque sample reçu de la Watch).
public struct ContentState: Codable, Hashable {
var heartRate: Double
var activeEnergyKcal: Double
var distanceMeters: Double
var elapsedSec: TimeInterval
var isLive: Bool // true = direct ; false = perdu/en pause
}
/// Données fixes (set au start, non modifiables).
var activityLabel: String // "Course", "Vélo", "Marche", "Renfo", ou "Séance"
var activitySymbol: String // SF Symbol (figure.run, bicycle, figure.walk, dumbbell)
var startedAt: Date
}