我在使用HKSampleQuery
获取重量的最新数据点时遇到麻烦。我已经正确设置了应用程序权限,但是HKQuantityTypeIdentifier.bodyMass
没有从Health应用程序返回最新的数据条目。
我应该如何使用HKSampleQuery
来获取体重的最新数据点?
我认为这是因为我为Weight
设置的0.0正在返回,并且在readWeight
上没有控制台输出
编辑1
我的代码包括调试过程,如下所示。
public func readWeight(result: @escaping (Double) -> Void) {
if (debug){print("Weight")}
let quantityType = HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.bodyMass)
let weightQuery = HKSampleQuery(sampleType: quantityType!, predicate: nil, limit: 1, sortDescriptors: nil) {
query, results, error in
if (error != nil) {
if (self.debug){print(error!)}
result(166.2) //Set as average weight for American
return
}
guard let results = results else {
if (self.debug){print("No results of query")}
result(166.2)
return
}
if (results.count == 0) {
if (self.debug){print("Zero samples")}
result(166.2)
return
}
guard let bodymass = results.first as? HKQuantitySample else {
if (self.debug){print("Type problem with weight")}
result(166.2)
return
}
if (self.debug){print("Weight" + String(bodymass.quantity.doubleValue(for: HKUnit.pound())))}
if (bodymass.quantity.doubleValue(for: HKUnit.pound()) != 0.0) {
result(bodymass.quantity.doubleValue(for: HKUnit.pound()))
} else {
result(166.2)
}
}
healthKitStore.execute(weightQuery)
}
该函数的用法如下:
var Weight = 0.0 //The probable reason that it returns 0.0
readWeight() { weight in
Weight = weight
}
编辑2
权限代码:
let healthKitTypesToRead : Set<HKQuantityType> = [
HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.dietaryWater)!,
HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.bodyMass)!,
HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.appleExerciseTime)!
]
let healthKitTypesToWrite: Set<HKQuantityType> = [
HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.dietaryWater)!
]
if (!HKHealthStore.isHealthDataAvailable()) {
if (self.debug){print("Error: HealthKit is not available in this Device")}
return
}
healthKitStore.requestAuthorization(toShare: healthKitTypesToWrite, read: healthKitTypesToRead) { (success, error) -> Void in
if (success) {
DispatchQueue.main.async() {
self.pointView.text = String(self.currentPoints())
}
}
if ((error) != nil) {
if (self.debug){print(error!)}
return
}
最佳答案
如HealthKit documentation(我强烈建议您完整阅读)中所述,除非您指定应如何返回样品,否则HKSampleQuery
不保证其返回的样品或返回它们的顺序。
对于您的情况,可以通过多种方式返回最新数据点。看一看HKSampleQuery
和以下方法:
init(sampleType:predicate:limit:sortDescriptors:resultsHandler:)
您可以提供返回样品的排序顺序,或限制返回样品的数量。
-HKSampleQuery Documentation
在您的代码中,您已经适当地限制了查询,以使其仅返回一个样本。这是正确的,并且可以避免用例中不必要的开销。但是,您的代码将
nil
指定为sortDescriptors
参数。这意味着查询可以以任意顺序返回样本(因此,返回给您的单个样本通常不是您要查找的内容)。排序描述符数组,用于指定此查询返回的结果的顺序。如果不需要特定顺序的结果,则传递nil。
注意
HealthKit定义了许多排序标识符(例如,
HKSampleSortIdentifierStartDate
和HKWorkoutSortIdentifierDuration
)。仅在查询中使用通过这些标识符创建的排序描述符。您不能使用它们对样本数组执行内存中排序。-HKSampleQuery.init(...) Documentation
因此,解决方案就是简单地提供一种排序描述符,该描述符要求
HKSampleQuery
按日期降序对样本进行排序(这意味着最新的将在列表中排在第一位)。我希望上述答案比简单的复制/粘贴解决问题所需的代码更有帮助。即使如此,仍可以在以下特定用例中为提供正确的示例的代码:
// Create an NSSortDescriptor
let sort = [
// We want descending order to get the most recent date FIRST
NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false)
]
let weightQuery = HKSampleQuery(sampleType: quantityType!, predicate: nil, limit: 1, sortDescriptors: sort) {
// Handle errors and returned samples...
}
关于ios - 从HKSampleQuery获取最新数据点,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44849723/