You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift如何获取Health Kit按设备类型区分的每日运动分类步数

实现方案

核心逻辑是在HealthKit查询时获取每一条步数样本的来源设备信息、关联运动属性,再自行按维度聚合,不需要依赖系统的时间区间分组能力。

1. 前置权限确认

确保你已经提前向用户申请了步数数据的读取权限,示例代码如下:

import HealthKit

let healthStore = HKHealthStore()
let stepType = HKObjectType.quantityType(forIdentifier: .stepCount)!

// 请求授权
healthStore.requestAuthorization(toShare: nil, read: [stepType]) { success, error in
    guard success else {
        // 处理权限拒绝逻辑
        return
    }
    // 权限获取成功后执行查询
}

2. 构造步数样本查询

直接查询目标日期内的所有步数原始样本,获取每个样本的设备来源、关联运动信息:

// 构造当日的查询时间范围
let calendar = Calendar.current
let startOfDay = calendar.startOfDay(for: Date())
let endOfDay = calendar.date(byAdding: .day, value: 1, to: startOfDay)!
let predicate = HKQuery.predicateForSamples(withStart: startOfDay, end: endOfDay, options: .strictStartDate)

// 构造查询对象
let query = HKSampleQuery(
    sampleType: stepType,
    predicate: predicate,
    limit: HKObjectQueryNoLimit,
    sortDescriptors: nil
) { _, samples, error in
    guard let samples = samples as? [HKQuantitySample], error == nil else {
        return
    }
    // 处理样本数据做分组聚合
    self.groupStepData(samples: samples)
}

healthStore.execute(query)

3. 按设备+运动组别分组聚合

自定义分组逻辑,分别按设备类型、运动类型两层维度拆分统计:

// 自定义分组结果结构
struct GroupedStepData {
    let deviceType: String // 设备类型:iPhone / Apple Watch
    let activityGroup: String // 运动组别:日常活动/步行/跑步/其他运动
    let totalSteps: Int // 该组总步数
}

func groupStepData(samples: [HKQuantitySample]) {
    var result: [GroupedStepData] = []
    
    // 第一层:按设备来源分组
    let deviceGrouped = Dictionary(grouping: samples) { sample -> String in
        let source = sample.source
        if source.name.contains("Apple Watch") || source.bundleIdentifier.contains("com.apple.health.watch") {
            return "Apple Watch"
        } else {
            return "iPhone"
        }
    }
    
    // 第二层:按运动组别分组并统计步数
    for (device, deviceSamples) in deviceGrouped {
        let activityGrouped = Dictionary(grouping: deviceSamples) { sample -> String in
            // 检查样本是否关联了运动记录
            if let workout = sample.workout {
                switch workout.workoutActivityType {
                case .walking: return "步行"
                case .running: return "跑步"
                case .hiking: return "徒步"
                case .cycling: return "骑行"
                default: return "其他运动"
                }
            } else {
                return "日常活动"
            }
        }
        
        // 计算每组总步数
        for (activity, activitySamples) in activityGrouped {
            let totalSteps = activitySamples.reduce(0) { partialResult, sample in
                partialResult + Int(sample.quantity.doubleValue(for: HKUnit.count()))
            }
            result.append(GroupedStepData(
                deviceType: device,
                activityGroup: activity,
                totalSteps: totalSteps
            ))
        }
    }
    
    //  result 即为最终需要的分组数据,可直接使用
}

注意事项

  • 如果需要排除第三方App写入的步数,可在分组时加判断过滤非苹果官方来源的样本
  • 数据量较大时可以改用HKStatisticsCollectionQuery配合groupBySource参数直接按设备聚合,查询效率更高
  • iOS16及以上系统可直接使用HKSourceRevision的productType属性更精准判断设备型号

内容的提问来源于stack exchange,提问作者dqualias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 18:51:01