iPhone健康APP睡眠数据获取返回0排查请求(附代码)
睡眠数据获取始终返回0的排查方案
我的应用已获得健康APP的睡眠数据权限,目前可正常获取步数和心率数据,但睡眠数据始终返回0。以下是用于获取睡眠数据的代码,请帮忙排查问题或遗漏点:
func fetchSleepData() { let sleepType = HKObjectType.categoryType(forIdentifier: .sleepAnalysis)! let startDate = Calendar.current.startOfDay(for: Date()) let endDate = Date() let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: .strictStartDate) let query = HKSampleQuery(sampleType: sleepType, predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: nil) { query, samples, error in guard let samples = samples as? [HKCategorySample], error == nil else { print("Failed to fetch sleep data: \(error?.localizedDescription ?? "No error")") return } // Calculate total sleep duration using .allAsleepValues let totalSleep = samples.reduce(0.0) { sum, sample in if HKCategoryValueSleepAnalysis.allAsleepValues.contains(HKCategoryValueSleepAnalysis(rawValue: sample.value) ?? .awake) { let sleepDuration = sample.endDate.timeIntervalSince(sample.startDate) return sum + sleepDuration } return sum } let sleepHours = totalSleep / 3600.0 // Convert seconds to hours print("Total Sleep Hours: \(sleepHours)") // Send Data to Backend self.sendDataToServer(data: ["sleep_hours": sleepHours]) } healthStore.execute(query) }
排查要点:
- 日期范围过窄:当前代码仅查询当天凌晨到现在的睡眠数据,若用户睡眠周期跨天(比如昨晚入睡今早醒来),这段数据会被完全遗漏。建议调整日期范围,比如查询过去24小时,或者前一天的0点到当天的0点(覆盖完整夜间睡眠)。
- Predicate选项限制:
.strictStartDate要求样本的startDate必须落在查询区间内,跨区间的睡眠记录(start在昨天,end在今天)会被过滤。可以尝试将options改为.strictEndDate或.none,确保包含部分时间在区间内的样本。 - 睡眠状态判断逻辑:当样本value无法解析为
HKCategoryValueSleepAnalysis时,代码默认按.awake处理,可能漏掉异常格式的睡眠记录。建议先打印所有获取到的samples的value和时间区间,确认数据是否被正确识别。 - 权限确认:再次检查
HKHealthStore的权限请求,确保明确请求了sleepAnalysis类型的读取权限,部分情况下可能只申请了步数、心率权限而遗漏睡眠权限。 - HealthKit数据验证:打开系统健康APP,确认存在有效的睡眠记录,排除数据本身不存在的情况。
内容的提问来源于stack exchange,提问作者Trigun Soni
相关产品推荐
相关产品推荐

