如何让Apple Health显示HKWorkoutEvent的训练事件名称?
问题:Apple Health中训练事件仅显示“Segment”,不显示具体动作名称
我需要将健身App的训练数据写入Apple Health,因此创建了HKWorkout样本,并在其中添加深蹲、辅助引体向上、杠铃弯举等训练事件。
现有代码
创建HKWorkoutEvent数组的代码:
var workoutEvents = [HKWorkoutEvent]() var metadata: [String: Any] = [:] workoutEvents = workout.workoutExercises.map { metadata[HKMetadataKeyWorkoutBrandName] = $0.exercise.name return HKWorkoutEvent( type: .segment, dateInterval: DateInterval(start: $0.timeStartedDate, duration: 60.0 * 6), metadata: metadata ) }
创建HKWorkout实例的代码:
let hkworkout = HKWorkout( activityType: .traditionalStrengthTraining, start: startDate, end: endDateUsing, workoutEvents: workoutEvents, totalEnergyBurned: caloriesBurnt, totalDistance: nil, totalSwimmingStrokeCount: nil, device: .local(), metadata: nil)
保存数据的代码:
HKHealthStore().save([hkworkout]) { success, error in }
遇到的问题
在Apple Health App中查看记录时,所有训练事件仅显示“Segment”字样,无法看到具体的训练项目名称及耗时信息,影响用户体验。我猜测是HKWorkoutEvent没有读取HKMetadataKeyWorkoutBrandName的值导致的,请问如何让Apple Health显示实际的训练事件名称?
解决方案
1. 替换正确的Metadata键
你误用了HKMetadataKeyWorkoutBrandName,这个键是用来标记App品牌名称的,并非训练事件的名称。要让Apple Health显示训练事件的自定义名称,需要使用**HKMetadataKeyWorkoutEventName**这个专属键。
2. 修改HKWorkoutEvent创建代码
每次创建训练事件时,单独生成metadata字典(避免复用导致的潜在问题),并替换为正确的键:
var workoutEvents = [HKWorkoutEvent]() workoutEvents = workout.workoutExercises.map { exercise in // 为每个训练事件单独创建metadata,使用HKMetadataKeyWorkoutEventName存储动作名称 let eventMetadata = [HKMetadataKeyWorkoutEventName: exercise.name] return HKWorkoutEvent( type: .segment, dateInterval: DateInterval(start: exercise.timeStartedDate, duration: 360.0), // 注意:这里的时长是固定6分钟,建议根据实际训练时长调整 metadata: eventMetadata ) }
3. 补充:记录更详细的训练数据(可选)
如果需要在Apple Health中显示动作的组数、次数、重量等细节,除了HKWorkoutEvent,还需要为每个动作创建对应的HKQuantitySample,并关联到HKWorkout上。例如记录重复次数:
// 假设每个exercise包含repetitionCount属性 let repetitionType = HKQuantityType.quantityType(forIdentifier: .repetitionCount)! let repetitionSamples = workout.workoutExercises.map { exercise in let quantity = HKQuantity(unit: HKUnit.count(), doubleValue: exercise.repetitionCount) return HKQuantitySample( type: repetitionType, quantity: quantity, start: exercise.timeStartedDate, end: exercise.timeStartedDate.addingTimeInterval(360.0), // 对应动作时长 metadata: [HKMetadataKeyWorkoutEventName: exercise.name] ) } // 保存时同时保存HKWorkout和样本 HKHealthStore().save([hkworkout] + repetitionSamples) { success, error in if let error = error { // 处理错误 print("保存失败:\(error.localizedDescription)") } }
4. 确认权限配置
确保你已经向用户请求了HKWorkoutType的写入权限,以及其他相关样本类型(如重复次数)的权限:
let healthStore = HKHealthStore() let typesToShare: Set<HKObjectType> = [ HKObjectType.workoutType(), HKQuantityType.quantityType(forIdentifier: .repetitionCount)! ] healthStore.requestAuthorization(toShare: typesToShare, read: nil) { success, error in // 处理权限请求结果 }
内容的提问来源于stack exchange,提问作者Emma
相关产品推荐
相关产品推荐

