来自 HealthKit 的数据最初丢失,然后在我再次尝试时出现 - 如何修复?
Data from HealthKit is initially missing, then comes in when I try again - how to fix?
我有一个正在 Swift 开发的 iOS 应用程序,作为该应用程序的一部分,它会收集当天的步数。
我第一次运行这个应用程序,计数是“0”,但是如果我点击界面中的一个按钮重新运行这个查询HK的功能,那么正确数字出现。
我猜这是因为 HK 需要一些时间来收集数据之类的,但我不确定如何修复它。也许 HK 可以在数据准备好后触发一个事件,然后我可以更新 UI?
这是从 HK 收集数据的例程。这个函数在应用程序启动时立即执行(它显示“今天0步”),然后如上所述,我可以点击一个按钮再次执行该函数(然后我得到正确的数字)。
func queryStepsSum() {
// prepare HK for the data
let endDate = NSDate() // right now
let startDate = NSCalendar.currentCalendar().dateBySettingHour(0, minute: 0, second: 0, ofDate: endDate, options: NSCalendarOptions())
let predicate = HKQuery.predicateForSamplesWithStartDate(startDate, endDate: endDate, options: .None)
let sumOption = HKStatisticsOptions.CumulativeSum
let statisticsSumQuery = HKStatisticsQuery( quantityType: self.stepsCount!, quantitySamplePredicate: predicate,
options: sumOption)
{ [unowned self] (query, result, error) in
if let sumQuantity = result?.sumQuantity() {
self.numberOfSteps = Int(sumQuantity.doubleValueForUnit(HKUnit.countUnit()))
}
}
// run the HK query
self.healthStore?.executeQuery(statisticsSumQuery)
// update the UI with the result
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.stepsLabel.text = "\(self.numberOfSteps) steps today";
});
}
您是在 viewDidLoad 中调用您的函数吗?您可以尝试在 viewDidAppear 中调用它。
如果这不起作用,也许有某种委托方法可以像您说的那样在数据准备就绪时更新您。我从未使用过 HealthKit,但我会检查一下是否能找到任何东西。
编辑:
这可能会使 UI 组件脱离后台线程。
尝试:
var numberOfSteps: Int! {
didSet {
self.stepsLabel.text = "\(self.numberOfSteps) steps today"
}
}
这应该可以消除您在后台线程上更新 UI 的错误。还要确保在我告诉你放置的闭包中删除你的调用。
您的代码在显示结果之前不会等待查询完成(查询是异步发生的)。您应该从查询的结果处理程序更新 UI,如下所示:
let statisticsSumQuery = HKStatisticsQuery( quantityType: self.stepsCount!, quantitySamplePredicate: predicate,
options: sumOption)
{ [unowned self] (query, result, error) in
dispatch_async(dispatch_get_main_queue()) {
if let sumQuantity = result?.sumQuantity() {
self.numberOfSteps = Int(sumQuantity.doubleValueForUnit(HKUnit.countUnit()))
self.stepsLabel.text = "\(self.numberOfSteps) steps today";
}
}
}
另请注意,由于查询结果处理程序在后台线程上运行,并且在该上下文中操作 UI 不安全,因此我已经将调度返回到主线程。
我有一个正在 Swift 开发的 iOS 应用程序,作为该应用程序的一部分,它会收集当天的步数。
我第一次运行这个应用程序,计数是“0”,但是如果我点击界面中的一个按钮重新运行这个查询HK的功能,那么正确数字出现。
我猜这是因为 HK 需要一些时间来收集数据之类的,但我不确定如何修复它。也许 HK 可以在数据准备好后触发一个事件,然后我可以更新 UI?
这是从 HK 收集数据的例程。这个函数在应用程序启动时立即执行(它显示“今天0步”),然后如上所述,我可以点击一个按钮再次执行该函数(然后我得到正确的数字)。
func queryStepsSum() {
// prepare HK for the data
let endDate = NSDate() // right now
let startDate = NSCalendar.currentCalendar().dateBySettingHour(0, minute: 0, second: 0, ofDate: endDate, options: NSCalendarOptions())
let predicate = HKQuery.predicateForSamplesWithStartDate(startDate, endDate: endDate, options: .None)
let sumOption = HKStatisticsOptions.CumulativeSum
let statisticsSumQuery = HKStatisticsQuery( quantityType: self.stepsCount!, quantitySamplePredicate: predicate,
options: sumOption)
{ [unowned self] (query, result, error) in
if let sumQuantity = result?.sumQuantity() {
self.numberOfSteps = Int(sumQuantity.doubleValueForUnit(HKUnit.countUnit()))
}
}
// run the HK query
self.healthStore?.executeQuery(statisticsSumQuery)
// update the UI with the result
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.stepsLabel.text = "\(self.numberOfSteps) steps today";
});
}
您是在 viewDidLoad 中调用您的函数吗?您可以尝试在 viewDidAppear 中调用它。 如果这不起作用,也许有某种委托方法可以像您说的那样在数据准备就绪时更新您。我从未使用过 HealthKit,但我会检查一下是否能找到任何东西。
编辑: 这可能会使 UI 组件脱离后台线程。 尝试:
var numberOfSteps: Int! {
didSet {
self.stepsLabel.text = "\(self.numberOfSteps) steps today"
}
}
这应该可以消除您在后台线程上更新 UI 的错误。还要确保在我告诉你放置的闭包中删除你的调用。
您的代码在显示结果之前不会等待查询完成(查询是异步发生的)。您应该从查询的结果处理程序更新 UI,如下所示:
let statisticsSumQuery = HKStatisticsQuery( quantityType: self.stepsCount!, quantitySamplePredicate: predicate,
options: sumOption)
{ [unowned self] (query, result, error) in
dispatch_async(dispatch_get_main_queue()) {
if let sumQuantity = result?.sumQuantity() {
self.numberOfSteps = Int(sumQuantity.doubleValueForUnit(HKUnit.countUnit()))
self.stepsLabel.text = "\(self.numberOfSteps) steps today";
}
}
}
另请注意,由于查询结果处理程序在后台线程上运行,并且在该上下文中操作 UI 不安全,因此我已经将调度返回到主线程。