从 HKSampleQuery 获取最新的数据点
Get most recent data point from HKSampleQuery
我无法使用 HKSampleQuery
获取最新的体重数据点。我已正确设置应用程序权限,但 HKQuantityTypeIdentifier.bodyMass
未从健康应用程序返回最新的数据条目。
我应该如何使用 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
不保证其 return 中的样本或顺序它 return 是它们 除非 您指定样本应该如何 returned。
对于您的情况,return可以通过多种方式获取最新的数据点。看看HKSampleQuery
和下面的方法:
init(sampleType:predicate:limit:sortDescriptors:resultsHandler:)
You can provide a sort order for the returned samples, or limit the number of samples returned.
在您的代码中,您已适当限制查询,使其仅 return 一个样本。这是正确的,并且避免了您的用例中不必要的开销。但是,您的代码为 sortDescriptors
参数指定了 nil
。这意味着查询可以 return 以任何它喜欢的顺序采样(因此,returned 给你的单个样本通常不是你要找的)。
An array of sort descriptors that specify the order of the results returned by this query. Pass nil if you don’t need the results in a specific order.
Note
HealthKit defines a number of sort identifiers (for example,
HKSampleSortIdentifierStartDate
and HKWorkoutSortIdentifierDuration
). Use the sort descriptors you create with these identifiers only in queries. You cannot use them to perform an in-memory sort of an array of samples.
因此,解决方案是简单地提供一个排序描述符,要求 HKSampleQuery
按日期降序排列样本(这意味着最新的样本将在列表中排在第一位)。
我希望上面的答案比解决问题所需的简单 copy/paste 代码更有帮助。尽管如此,为 这个特定 用例提供正确样本的代码如下:
// 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...
}
我无法使用 HKSampleQuery
获取最新的体重数据点。我已正确设置应用程序权限,但 HKQuantityTypeIdentifier.bodyMass
未从健康应用程序返回最新的数据条目。
我应该如何使用 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
不保证其 return 中的样本或顺序它 return 是它们 除非 您指定样本应该如何 returned。
对于您的情况,return可以通过多种方式获取最新的数据点。看看HKSampleQuery
和下面的方法:
init(sampleType:predicate:limit:sortDescriptors:resultsHandler:)
You can provide a sort order for the returned samples, or limit the number of samples returned.
在您的代码中,您已适当限制查询,使其仅 return 一个样本。这是正确的,并且避免了您的用例中不必要的开销。但是,您的代码为 sortDescriptors
参数指定了 nil
。这意味着查询可以 return 以任何它喜欢的顺序采样(因此,returned 给你的单个样本通常不是你要找的)。
An array of sort descriptors that specify the order of the results returned by this query. Pass nil if you don’t need the results in a specific order.
Note
HealthKit defines a number of sort identifiers (for example,HKSampleSortIdentifierStartDate
andHKWorkoutSortIdentifierDuration
). Use the sort descriptors you create with these identifiers only in queries. You cannot use them to perform an in-memory sort of an array of samples.
因此,解决方案是简单地提供一个排序描述符,要求 HKSampleQuery
按日期降序排列样本(这意味着最新的样本将在列表中排在第一位)。
我希望上面的答案比解决问题所需的简单 copy/paste 代码更有帮助。尽管如此,为 这个特定 用例提供正确样本的代码如下:
// 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...
}