跳到主要内容

健康

读取系统健康 App 数据。需要"健康"权限,首次调用会弹窗,用户拒绝后再调用会失败。

在 App 的 设置 → 健康权限 里可以随时重新请求,或者跳转到系统设置中按项目精细管理。

步数 / 距离 / 活动能量 / 楼层

这一组接口都是当地零点至现在的累计值,直接返回 number(不是 JSON 字符串),数据会在内部缓存 5 分钟以减少授权抖动。

接口单位说明
Health.getStepsToday()今日累计步数
Health.getActiveEnergyToday()kcal今日活动能量
Health.getDistanceToday()今日步行 + 跑步距离
Health.getFlightsClimbedToday()今日攀爬楼层
const steps = await Health.getStepsToday()
const distance = await Health.getDistanceToday()
this.steps = `${steps} 步 · ${(distance / 1000).toFixed(2)} km`

任意区间步数

Health.getStepsBetween(startMs, endMs) 取指定时间段的累计步数,参数为毫秒时间戳

const now = Date.now()
const yesterday = now - 24 * 3600 * 1000
const steps = await Health.getStepsBetween(yesterday, now)
console.log(`过去 24 小时:${steps}`)

心率

返回 JSON 字符串,结构 { value, unit, date },date 是毫秒时间戳。

接口说明
Health.getLatestHeartRate()最近一次心率读数(bpm)
Health.getRestingHeartRate()最近一次静息心率(bpm)
const result = await Health.getLatestHeartRate()
const { value, date } = JSON.parse(result)
this.hr = `${Math.round(value)} bpm`

返回示例:

{
"value": 72.0,
"unit": "bpm",
"date": 1700000000000
}

体重

Health.getLatestBodyMass() 取最近一次体重数据,单位 kg

const r = await Health.getLatestBodyMass()
const { value, date } = JSON.parse(r)
this.weight = `${value.toFixed(1)} kg`

今日活动环

Health.getActivitySummaryToday() 汇总活动 / 锻炼 / 站立三个环以及各自目标,返回 JSON 字符串。

const r = await Health.getActivitySummaryToday()
const a = JSON.parse(r)

this.move = `${Math.round(a.activeEnergyBurned)} / ${Math.round(a.activeEnergyBurnedGoal)} kcal`
this.exercise = `${Math.round(a.exerciseTime)} / ${Math.round(a.exerciseTimeGoal)} min`
this.stand = `${Math.round(a.standHours)} / ${Math.round(a.standHoursGoal)} h`

返回结构:

{
"activeEnergyBurned": 320.5,
"activeEnergyBurnedGoal": 400,
"exerciseTime": 25,
"exerciseTimeGoal": 30,
"standHours": 10,
"standHoursGoal": 12,
"date": 1700000000000
}

锻炼目标和站立目标如果用户没设,会返回 0

训练记录

Health.getRecentWorkouts(days) 拉取最近 N 天的训练记录,按开始时间倒序。days0 或负数时按 7 天处理。

const r = await Health.getRecentWorkouts(7)
const workouts = JSON.parse(r)
this.count = `最近 7 天 ${workouts.length} 次训练`

每条结构:

{
"activityType": 37,
"startDate": 1700000000000,
"endDate": 1700001800000,
"duration": 1800,
"activeEnergyBurned": 280,
"totalDistance": 4500
}
  • activityType 对应 HKWorkoutActivityType 的 raw value(如 37 = walking,52 = running)。
  • duration 单位,activeEnergyBurned 单位 kcal,totalDistance 单位,数据缺失时为 null

最近一晚的睡眠汇总

const result = await Health.getLastSleepDetail()
const obj = JSON.parse(result)

obj.sleepDatas.forEach(item => {
console.log(`${categoryName(item.category)} - ${formatDuration(item.seconds)}`)
})

返回结构:

{
"startDate": 1738854640763,
"endDate": 1738879690763,
"sleepDatas": [
{ "category": 4, "seconds": 3000 },
{ "category": 3, "seconds": 15030 },
{ "category": 2, "seconds": 2700 },
{ "category": 5, "seconds": 4320 },
{ "category": 99,"seconds": 22350 }
]
}

category 含义

category含义备注
2清醒不计入睡眠总时长
3核心睡眠占大头
4深度睡眠
5眼动睡眠 (REM)
99总睡眠时长(不含清醒)由 Omni 汇总而来

完整睡眠片段(最近 48 小时)

如果你想自己画时序图、按片段分析:

const result = await Health.getSleepData()
const arr = JSON.parse(result)
console.log(arr.length)

返回数组,每项是一个时间段:

{
"startDate": 1738854640763,
"endDate": 1738855510763,
"value": 3,
"sleepState": "sleepCore"
}

sleepState 字符串和 value 一一对应:

valuesleepState含义
1inBed在床上(尚未入睡)
2Awake清醒
3sleepCore核心睡眠
4asleepDeep深度睡眠
5asleepREM眼动睡眠
样例返回(只展示前几项)
[
{ "startDate": 1738854640763, "endDate": 1738855510763, "value": 3, "sleepState": "sleepCore" },
{ "startDate": 1738855510763, "endDate": 1738855870763, "value": 4, "sleepState": "asleepDeep" },
{ "startDate": 1738855870763, "endDate": 1738855900763, "value": 3, "sleepState": "sleepCore" },
{ "startDate": 1738855900763, "endDate": 1738855990763, "value": 2, "sleepState": "Awake" },
...
]

完整数据通常有几十到上百段,运行后用 console.log 自己看。

例:展示昨晚总时长

const result = await Health.getLastSleepDetail()
const obj = JSON.parse(result)
const total = obj.sleepDatas.find(d => d.category === 99)?.seconds || 0

const h = Math.floor(total / 3600)
const m = Math.floor((total % 3600) / 60)
this.sleep = `${h}${m}`

text 组件填 {sleep} → 显示 7时10分

注意

  • 没有 Apple Watch / 没记录:睡眠相关接口仅读取 Apple Watch 写入的数据,可能为空。其它接口(步数、心率等)也会读取 iPhone 自身数据。
  • iOS 健康权限:首次调用会弹窗。用户拒绝后,后续调用会直接返回错误。可通过 App 的"设置 → 健康权限"重新请求或跳转系统设置管理。
  • 数据有滞后:Watch 同步到 iPhone 通常要几分钟到一小时。
  • 小组件内存限制:健康相关接口在小组件中不会弹权限框,仅当主 App 已授权时才能正常读取。