HKStatisticsCollectionQuery的 initialResultsHandler针对一个特定用户返回空结果——已授予读取权限、数据存在、重新安装后仍然存在
环境: iPhone 13 Pro,iOS 26.5。仅影响众多用户中的一位;在我们的测试设备上无法重现。
我们使用 HKStatisticsCollectionQuery 来读取统计屏幕的步数数据。对于某个特定用户,查询的 initialResultsHandler 似乎返回 results == nil(成功分支从未执行),因此完成回调从不被调用,屏幕显示无限旋转的加载指示。
func getDayHourlySteps(currentDay: Date, completion: @escaping ([HKStatistics]) -> Void) {
let anchorComponents = Calendar.current.dateComponents([.day, .month, .year, .hour], from: currentDay)
let anchorDate = Calendar.current.date(from: anchorComponents)!
var interval = DateComponents(); interval.hour = 1
let manualPredicate = NSPredicate(format: "metadata.%K != YES", HKMetadataKeyWasUserEntered)
let query = HKStatisticsCollectionQuery(
quantityType: HKQuantityType.quantityType(forIdentifier: .stepCount)!,
quantitySamplePredicate: manualPredicate,
options: .cumulativeSum,
anchorDate: anchorDate,
intervalComponents: interval
)
query.initialResultsHandler = { _, results, error in
guard let results else {
// For the affected user we suspect we land here (results == nil).
// What HKError shows up here? (we are adding logging now)
return
}
// ...enumerate & completion...
}
healthStore.execute(query)
}
我们已确认 / 排除如下:
- 对
stepCount的读取授权已被授予(用户在HealthKit窗口将其开启)。 - Apple Health应用为该用户显示步数数据(因此数据存在)。
- 同一用户的一个更粗粒度的查询(2年区间)成功,而按小时粒度的查询似乎失败——类型、谓词、选项、授权均相同。
- 该症状在应用重新安装、设备重启,以及重新授权Health权限后仍然存在。
- 权限被拒绝时返回空结果(按Apple文档),而不是错误——因此这并非简单拒绝。
- 据我们所知,这不是
errorDatabaseInaccessible(前台、设备解锁时)。
问题:
- 在读取授权已授予且数据存在的情况下,什么原因会导致
HKStatisticsCollectionQuery.initialResultsHandler持续返回results == nil(带有错误)?仅在一个设备/账户上持续发生? errorHealthDataRestricted是否会在没有MDM/受控配置文件的情况下发生吗(也就是在普通消费者设备上)?实际会触发它的设备/账户状态有哪些?- 对同一用户,粗粒度查询成功而同一类型的小时粒度查询失败,这是预期的吗?
我们将在下次发生时记录实际的 HKError 代码+ authorizationStatus,若能提供产生此问题的条件的见解,我们将不胜感激。
解决方案
有一点需要考虑的是,查询仅对元数据进行过滤:
let manualPredicate = NSPredicate(format: "metadata.%K != YES", HKMetadataKeyWasUserEntered)
没有日期谓词,因此HealthKit在后续枚举单日统计数据之前,可以自由处理所有匹配的步数样本。
我不知道这是否就是问题的根源,但值得尝试使用带日期边界的谓词,以减少查询需要处理的数据量:
let startOfDay = Calendar.current.startOfDay(for: currentDay)
let endOfDay = Calendar.current.date(byAdding: .day, value: 1, to: startOfDay)!
let datePredicate = HKQuery.predicateForSamples(
withStart: startOfDay,
end: endOfDay,
options: .strictStartDate
)
let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [
datePredicate,
manualPredicate
])
也就是说,仍然不清楚为何对同一用户,按小时粒度的 HKStatisticsCollectionQuery 会持续失败,而粗粒度查询却成功。实际的 HKError 代码很可能是理解正在发生的情况的关键。在你拿到那个之前,很难判断这是HealthKit的错误、数据相关的问题,还是环境问题。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。