WWDC Quick Look 💓 By SwiftGGTeam
Build custom workouts with WorkoutKit

Build custom workouts with WorkoutKit

观看原视频

Highlight

WorkoutKit 是一个全新的 Swift 框架,让开发者能在 iOS 和 watchOS 应用中创建、预览和调度自定义训练计划并同步到 Apple Watch 的训练 app;支持四种训练类型:单目标训练、配速训练、铁人三项训练和自定义间歇训练,每种类型都提供预定义的模型和系统级 UI。


核心内容

健身应用开发者一直面临一个难题:用户想在 Apple Watch 上使用自定义训练计划,但实现起来复杂又不直观。

以前要实现这个功能,开发者需要在 watchOS 上重新构建整个训练逻辑,包括计时、提醒、目标追踪和界面展示。工作量巨大,而且用户体验与系统自带训练 app 不一致——用户已经习惯了训练 app 的交互,第三方实现很难达到同样的流畅度。

Apple 在 iOS 17 和 watchOS 10 中推出了 WorkoutKit 框架。这个框架提供了预定义的训练模型,开发者只需要描述训练内容,系统会自动处理 UI 和同步。

WorkoutKit 支持四种训练类型。

单目标训练(SingleGoalWorkout):最简单的形式,用户完成一个目标——跑完 5 公里、消耗 500 卡路里或坚持 30 分钟。

配速训练(PacerWorkout):在规定时间内完成规定距离。用户训练马拉松配速时,在 50 分钟内跑完 10 公里,系统实时显示是否在目标配速范围内。

铁人三项训练(SwimBikeRunWorkout):支持游泳、骑行和跑步的无缝切换。运动员不需要在项目切换时手动停止和重启训练。

自定义间歇训练(CustomWorkout):最灵活的类型。开发者可以定义热身、冷身和多个重复的训练块,每个训练块包含工作和恢复阶段,支持自定义目标和提醒。

构建好训练后,用 WorkoutPlan 包装,可以打开系统训练 app、导出数据或通过 WorkoutScheduler 定时同步到 Apple Watch。

定时同步功能解决了另一个痛点:用户想提前规划一周训练,不需要每次都打开 app。训练计划会在 Apple Watch 的训练 app 中独立显示,带你的 app 图标和名称。


详细内容

单目标训练(02:15

SingleGoalWorkout 是最简单的训练类型,适合「完成一个目标」的场景。

import WorkoutKit

// 创建一个 5 公里跑步训练
let workout = SingleGoalWorkout(
    activity: .running,
    location: .outdoor,
    goal: .distance(.kilometers(5))
)

// 包装成训练计划
let plan = WorkoutPlan(workout, id: "5k-run")

关键点:

  • activity 指定运动类型(running、cycling、swimming 等)
  • location 指定场景(outdoor、indoor)
  • goal 可以是 .distance.time.energy
  • WorkoutPlan 提供统一的接口来打开或导出训练

配速训练(05:30

PacerWorkout 同时设置距离和时间目标,适合配速练习。

// 创建配速训练:50 分钟内跑完 10 公里
let workout = PacerWorkout(
    activity: .running,
    location: .outdoor,
    distance: .kilometers(10),
    time: .minutes(50)
)

let plan = WorkoutPlan(workout, id: "10k-pacer")

关键点:

  • 配速训练同时显示距离和时间的完成进度
  • 系统自动判断用户是否在目标配速范围内
  • 适合马拉松训练或节奏跑

自定义间歇训练(08:45

CustomWorkout 支持结构化训练,适合 HIIT、Tabata 等场景。

// 创建工作阶段:跑 1 公里,速度在 8-10 mph
let workStep = WorkoutStep(
    goal: .distance(.kilometers(1)),
    alert: .speed(.milesPerHour(8...10), metric: .speed)
)

// 创建恢复阶段:心率降到 140 以下
let recoveryStep = WorkoutStep(
    goal: .time(.minutes(3)),
    alert: .heartRate(120...140)
)

// 创建训练块:重复 4 次
let block = IntervalBlock(
    steps: [workStep, recoveryStep],
    iterations: 4
)

// 组装完整训练:热身 + 训练块 + 冷身
let workout = CustomWorkout(
    activity: .running,
    location: .outdoor,
    displayName: "HIIT 跑步",
    warmup: WorkoutStep(goal: .time(.minutes(5))),
    blocks: [block],
    cooldown: WorkoutStep(goal: .time(.minutes(5)))
)

let plan = WorkoutPlan(workout, id: "hiit-run")

关键点:

  • WorkoutStep 定义单个阶段,包含 goalalert
  • WorkoutGoal 支持 distance、time、energy、open 四种类型
  • WorkoutAlert 提供实时反馈:速度、心率、功率、踏频
  • IntervalBlock 通过 iterations 控制重复次数
  • warmupcooldown 可选

训练提醒类型(12:20

WorkoutAlert 提供多种提醒方式。

// 速度提醒(区间模式)
.speed(.milesPerHour(8...10), metric: .speed)

// 速度提醒(阈值模式)
.speed(.above(.milesPerHour(8)), metric: .speed)

// 心率区间提醒
.heartRate(120...140)

// 心率区间提醒(用预定义区间)
.heartRate(zone: .zone3)

// 功率提醒
.power(.watts(200...250))

// 踏频提醒
.cadence(.stepsPerMinute(85...95))

关键点:

  • 每种提醒支持区间(range)和阈值(threshold)两种模式
  • metric 参数指定显示的度量类型
  • 不同运动类型支持不同的提醒(骑行支持功率,游泳不支持踏频)
  • 系统在用户偏离目标时提供触觉和声音反馈

铁人三项训练(15:50

SwimBikeRunWorkout 支持三项运动无缝切换。

let workout = SwimBikeRunWorkout(
    activities: [
        .swim(.distance(.meters(1500))),
        .bike(.distance(.kilometers(40))),
        .run(.distance(.kilometers(10)))
    ],
    displayName: "奥运距离铁人三项"
)

let plan = WorkoutPlan(workout, id: "olympic-triathlon")

关键点:

  • activities 数组按顺序定义三个项目
  • 每个项目可独立设置目标
  • 系统自动处理项目切换时的数据记录

打开训练 app(18:30

创建 WorkoutPlan 后可以打开系统训练 app 或导出数据。

// 在 Apple Watch 上打开训练 app
plan.openInWorkoutApp()

// 导出为 JSON 数据
let data = try plan.dataRepresentation(as: .json)

关键点:

  • openInWorkoutApp() 在 Apple Watch 上直接启动训练
  • dataRepresentation 支持导出为 JSON 格式
  • 在 iPhone 上调用会自动将计划同步到 Apple Watch

定时同步训练(21:00

WorkoutScheduler 支持提前规划训练,定时同步到 Apple Watch。

// 请求授权
await WorkoutScheduler.shared.requestAuthorization()

// 检查授权状态
let state = WorkoutScheduler.shared.authorizationState

// 调度训练计划
let scheduler = WorkoutScheduler.shared
let scheduledDate = Calendar.current.date(
    byAdding: .hour,
    value: 1,
    to: Date()
)!

try await scheduler.schedule(plan, at: scheduledDate)

// 查看已调度的训练
let workouts = scheduler.scheduledWorkouts

// 标记完成
try await scheduler.markComplete(plan, at: Date())

// 取消调度
try await scheduler.remove(plan, at: scheduledDate)

关键点:

  • 首次调度前必须请求用户授权
  • maxAllowedScheduledWorkoutCount 限制可调度训练数量
  • 已调度训练在 Apple Watch 训练 app 顶部显示
  • 训练完成后可调用 markComplete 更新状态

检查支持性(24:15

不同运动类型支持不同的目标和提醒,先检查再构建。

// 检查运动类型是否支持
CustomWorkout.supportsActivity(.running)

// 检查目标是否支持
CustomWorkout.supportsGoal(
    .heartRate(.above(160)),
    activity: .running,
    location: .outdoor
)

// 检查提醒是否支持
CustomWorkout.supportsAlert(
    .power(.watts(200...250)),
    activity: .cycling,
    location: .indoor
)

关键点:

  • 游泳不支持功率和踏频提醒
  • 室内跑步不支持距离目标(GPS 不可用)
  • 先调用 supportsGoalsupportsAlert 检查,避免运行时错误

核心启发

  • 做什么:为健身 app 添加自定义训练计划功能,让用户按预设方案训练。为什么值得做:WorkoutKit 使用系统级 UI,用户不需要学习新交互。怎么开始:从 SingleGoalWorkout 入手,在 app 中添加「创建训练计划」按钮,逐步扩展到 CustomWorkout。

  • 做什么:为马拉松跑者提供配速训练计划。为什么值得做:PacerWorkout 实时显示配速进度,是马拉松训练的刚需。怎么开始:创建「配速训练」模板页,让用户输入距离和完赛时间,生成 PacerWorkout 并调度到比赛日。

  • 做什么:为 HIIT 爱好者提供可自定义的间歇训练编辑器。为什么值得做:CustomWorkout 支持灵活的阶段定义和实时提醒,完全满足 HIIT 的结构化需求。怎么开始:设计拖拽式「训练编辑器」,让用户添加工作/恢复阶段、设置目标和提醒,生成 CustomWorkout 同步到 Apple Watch。

  • 做什么:为铁人三项运动员提供一键训练计划。为什么值得做:SwimBikeRunWorkout 自动处理项目切换,不丢失训练数据。怎么开始:预置奥运距离、半程铁人等常见模板,用户一键生成并调度训练。

  • 做什么:利用 WorkoutScheduler 做训练日历管理。为什么值得做:用户可以提前规划一周训练,计划自动显示在 Apple Watch 训练 app 中,提升用户留存。怎么开始:在 app 中添加「训练日历」视图,展示已调度训练,支持增删改查,调用 scheduleremove 同步到系统。


关联 Session

评论

GitHub Issues · utterances