Press kit / Technology

On-device AI, and the platform work behind it

FitnessKit is the operating system for personal trainers, and every draft it writes is generated on device.

A trainer's day is a queue of small writing jobs: replying to check-ins, writing monthly progress reports, pinning form cues to the rep that needs them, deciding what each client does next. FitnessKit drafts all of it with Apple's Foundation Models framework, running entirely on device, and puts it in one Approval Queue. The trainer edits or approves; nothing sends without them.

On-device is the product, not an implementation detail. The data these drafts are written from — training history, sleep, recovery, injuries, body-form video, chat with a coach — never leaves the phone for inference. It works in a gym basement with no signal.

The AI is deliberately not autonomous: a flow earns autopilot only after its drafts have been approved untouched.

Platform adoption

Counts below are verified by grepping Modules/*/Sources (excluding tests and build output); app- and widget-target rows are verified separately in FitnessWorkout/ and FitnessWorkoutWidget/.

Technology Verified reality
Foundation Models 32 module source files import FoundationModels across WorkoutAIService and CoachAIService; 87 @Generable/@Guide guided-generation sites (26 @Generable, 61 @Guide); availability is gated in WorkoutAIAvailability.swift, with retry guardrails in GuardrailRetry.swift.
App Intents 6 shipped intents (4 in Modules/FitnessKitIntents, 2 in the app target), a ClientEntity with EntityStringQuery, IndexedEntity Spotlight indexing, OpenClientIntent tap-through, an OpenApprovalQueueControlIntent for Control Center, and 5 App Shortcuts with 2 phrases each in English and Latin American Spanish.
WidgetKit 4 shipped widgets — ClientTrainingWidget, ClientPendingWidget, ApprovalWidget, and TrainerTodayWidget — covering Home Screen and StandBy, Lock Screen families for Approval (.accessoryCircular, .accessoryRectangular, .accessoryInline) and Client Pending (.accessoryRectangular, .accessoryInline), Smart Stack relevances on the queue and pending widgets, and a Control Center control for the Approval Queue.
Interactive snippets PendingApprovalsIntent returns a ShowsSnippetView snippet — count and breakdown by draft kind, with a Review button that opens the queue and a RefreshApprovalsSnippetIntent to update it in place.
ActivityKit ActivityWorkoutLiveActivityWidget ships a Live Activity with Dynamic Island expanded, compact, and minimal states, plus push-token wiring for remote updates.
Vision + Core ML 4 module source files import Vision, 2 import CoreML; FitnessKit uses VNDetectHumanBodyPoseRequest, VNDetectHumanBodyPose3DRequest, and an on-device equipment classifier.
HealthKit HealthStore reads heart rate, active energy, steps, sleep, HRV, resting heart rate, wrist temperature, and respiratory rate; completed workouts are written back out.
Swift 6 The app project's production configurations include SWIFT_VERSION = 6.0 and SWIFT_STRICT_CONCURRENCY = complete, alongside 45 SwiftPM modules on swift-tools-version: 6.3.
SwiftUI + Observation 458 module source files import SwiftUI; module sources contain 153 @Observable declarations; Modules uses only 4 representable bridges.
Liquid Glass 4 source files use .glassEffect(...), centralized through DesignSystem/ViewModifiers/GlassModifier.swift.
TipKit / Swift Charts / EventKit / StoreKit 18 / 10 / 1 / 1 module source files import these frameworks respectively.
iPad Adaptive two-column dashboards ship via DashboardGrid, with split-view flows where the workflow benefits from persistent context.

Explicitly not claimed: watchOS, visionOS, macOS, tvOS, ARKit, RealityKit, SwiftData, App Intent Assistant schemas, Visual Intelligence, interactive widget buttons.

App Intents shipped, but the restraint is deliberate

Adoption went from zero to six trainer-facing intents, a ClientEntity with its query, Siri phrases in both locales, and Spotlight search over the roster. The interesting part is not that the surface exists; it is what the app refuses to do.

Nothing an intent says names a client. Every result answers with counts and times. A result is read aloud — on a Lock Screen in a busy gym, through CarPlay, or on a HomePod — to whoever is in earshot, and the app holds these people's health data, chat, and body-form video. The trainer who needs to know who opens the app, which is one tap from the answer. The same line holds in Spotlight, where the index carries a name and never the app's opinion of that person: no at-risk state, no adherence, no inferred judgement.

No intent approves anything. PendingApprovalsIntent reports what is waiting and stops; OpenApprovalQueueIntent opens the queue so the drafts can actually be read. Approving work you have not read is autopilot, and autopilot is earned through AutopilotTrustCalculator, not toggled. A voice back door around that would undermine the feature the business model rests on.

No snapshot-backed intent asserts a number it has not checked. The app refuses to speak a count once the mirror is stale, because a widget showing an old number is visibly a widget and Siri saying "four are waiting" is an assertion.

The one nudge that writes asks for confirmation first, re-validates the client against the live roster, and routes through the demo-aware worker so a sample-client action can never reach a real client.

More

See the press kit for the icon, screenshots, and preview video, and the accessibility statement backing the Accessibility Nutrition Labels declaration.