HealthKit 在间隔之间获取数据
HealthKit fetch data between interval
我在掌握 HealthKit 时遇到了一点问题。我想在特定时间从 HealthKit 获取心率。
我过去这样做过(直到我注意到 phone 被锁定时我无法获取数据)
func retrieveMostRecentHeartRateSample(completionHandler: (sample: HKQuantitySample) -> Void) {
let sampleType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)
let predicate = HKQuery.predicateForSamplesWithStartDate(NSDate.distantPast() as! NSDate, endDate: NSDate(), options: HKQueryOptions.None)
let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false)
let query = HKSampleQuery(sampleType: sampleType, predicate: predicate, limit: 1, sortDescriptors: [sortDescriptor])
{ (query, results, error) in
if error != nil {
println("An error has occured with the following description: \(error.localizedDescription)")
} else {
let mostRecentSample = results[0] as! HKQuantitySample
completionHandler(sample: mostRecentSample)
}
}
healthKitStore.executeQuery(query)
}
var observeQuery: HKObserverQuery!
func startObservingForHeartRateSamples() {
println("startObservingForHeartRateSamples")
let sampleType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)
if observeQuery != nil {
healthKitStore.stopQuery(observeQuery)
}
observeQuery = HKObserverQuery(sampleType: sampleType, predicate: nil) {
(query, completionHandler, error) in
if error != nil {
println("An error has occured with the following description: \(error.localizedDescription)")
} else {
self.retrieveMostRecentHeartRateSample {
(sample) in
dispatch_async(dispatch_get_main_queue()) {
let result = sample
let quantity = result.quantity
let count = quantity.doubleValueForUnit(HKUnit(fromString: "count/min"))
println("sample: \(count)")
heartChartDelegate?.updateChartWith(count)
}
}
}
}
healthKitStore.executeQuery(observeQuery)
}
每次HealthKit发生变化时,这段代码都会获取最新的样本。但正如我之前所说,当 phone 被锁定时它不会更新。我尝试使用:
self.healthKitStore.enableBackgroundDeliveryForType(HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate), frequency: HKUpdateFrequency.Immediate) { (success, error) in
if success{
println("success")
} else {
println("fail")
}
}
但这没有用,而且我发现有一个错误,Apple 说它没有按他们想要的方式工作。猜猜这是一些安全问题。
但后来我想,也许我可以在 startTime 和 endTime 之间请求样本。例如我有 EndTime(2015-05-31 10:34:45 +0000) 和 StartTime(2015-05-31 10:34:35 +0000) 。
所以我的问题是如何在这两次之间获取心率样本。
我想我必须在
HKQuery.predicateForSamplesWithStartDate(myStartTime, endDate: myEndTime, options: HKQueryOptions.None)
但是当我尝试时它没有找到任何东西。也许我错了...
我在胸前使用心率监测器,我知道我在开始和结束时间内在 healthKit 中获得了一些值。
编辑:
好的,我试过了,它有时会起作用,但并非总是如此。有人有想法吗?
func fetchHeartRates(endTime: NSDate, startTime: NSDate){
let sampleType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)
let predicate = HKQuery.predicateForSamplesWithStartDate(startTime, endDate: endTime, options: HKQueryOptions.None)
let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false)
let query = HKSampleQuery(sampleType: sampleType, predicate: predicate, limit: 100, sortDescriptors: [sortDescriptor])
{ (query, results, error) in
if error != nil {
println("An error has occured with the following description: \(error.localizedDescription)")
} else {
for r in results{
let result = r as! HKQuantitySample
let quantity = result.quantity
let count = quantity.doubleValueForUnit(HKUnit(fromString: "count/min"))
println("sample: \(count) : \(result)")
}
}
}
healthKitStore.executeQuery(query)
}
编辑 2:
它工作正常,但我不能像我那样称呼它。所以我在几秒钟后取了它,它工作正常:)
...But as I said earlier, it won't update when the phone is locked...Guess it is some security-thing.
你是对的。
来自HealthKit Framework Reference:
Because the HealthKit store is encrypted, your app cannot read data from the store when the phone is locked. This means your app may not be able to access the store when it is launched in the background. However, apps can still write data to the store, even when the phone is locked. The store temporarily caches the data and saves it to the encrypted store as soon as the phone is unlocked.
如果您希望您的应用在有新结果时收到提醒,您应该查看 Managing Background Delivery:
enableBackgroundDeliveryForType:frequency:withCompletion:
Call this method to register your app for background updates. HealthKit wakes your app whenever new samples of the specified type are saved to the store. Your app is called at most once per time period defined by the specified frequency.
我在掌握 HealthKit 时遇到了一点问题。我想在特定时间从 HealthKit 获取心率。 我过去这样做过(直到我注意到 phone 被锁定时我无法获取数据)
func retrieveMostRecentHeartRateSample(completionHandler: (sample: HKQuantitySample) -> Void) {
let sampleType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)
let predicate = HKQuery.predicateForSamplesWithStartDate(NSDate.distantPast() as! NSDate, endDate: NSDate(), options: HKQueryOptions.None)
let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false)
let query = HKSampleQuery(sampleType: sampleType, predicate: predicate, limit: 1, sortDescriptors: [sortDescriptor])
{ (query, results, error) in
if error != nil {
println("An error has occured with the following description: \(error.localizedDescription)")
} else {
let mostRecentSample = results[0] as! HKQuantitySample
completionHandler(sample: mostRecentSample)
}
}
healthKitStore.executeQuery(query)
}
var observeQuery: HKObserverQuery!
func startObservingForHeartRateSamples() {
println("startObservingForHeartRateSamples")
let sampleType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)
if observeQuery != nil {
healthKitStore.stopQuery(observeQuery)
}
observeQuery = HKObserverQuery(sampleType: sampleType, predicate: nil) {
(query, completionHandler, error) in
if error != nil {
println("An error has occured with the following description: \(error.localizedDescription)")
} else {
self.retrieveMostRecentHeartRateSample {
(sample) in
dispatch_async(dispatch_get_main_queue()) {
let result = sample
let quantity = result.quantity
let count = quantity.doubleValueForUnit(HKUnit(fromString: "count/min"))
println("sample: \(count)")
heartChartDelegate?.updateChartWith(count)
}
}
}
}
healthKitStore.executeQuery(observeQuery)
}
每次HealthKit发生变化时,这段代码都会获取最新的样本。但正如我之前所说,当 phone 被锁定时它不会更新。我尝试使用:
self.healthKitStore.enableBackgroundDeliveryForType(HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate), frequency: HKUpdateFrequency.Immediate) { (success, error) in
if success{
println("success")
} else {
println("fail")
}
}
但这没有用,而且我发现有一个错误,Apple 说它没有按他们想要的方式工作。猜猜这是一些安全问题。
但后来我想,也许我可以在 startTime 和 endTime 之间请求样本。例如我有 EndTime(2015-05-31 10:34:45 +0000) 和 StartTime(2015-05-31 10:34:35 +0000) 。 所以我的问题是如何在这两次之间获取心率样本。
我想我必须在
HKQuery.predicateForSamplesWithStartDate(myStartTime, endDate: myEndTime, options: HKQueryOptions.None)
但是当我尝试时它没有找到任何东西。也许我错了...
我在胸前使用心率监测器,我知道我在开始和结束时间内在 healthKit 中获得了一些值。
编辑:
好的,我试过了,它有时会起作用,但并非总是如此。有人有想法吗?
func fetchHeartRates(endTime: NSDate, startTime: NSDate){
let sampleType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)
let predicate = HKQuery.predicateForSamplesWithStartDate(startTime, endDate: endTime, options: HKQueryOptions.None)
let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false)
let query = HKSampleQuery(sampleType: sampleType, predicate: predicate, limit: 100, sortDescriptors: [sortDescriptor])
{ (query, results, error) in
if error != nil {
println("An error has occured with the following description: \(error.localizedDescription)")
} else {
for r in results{
let result = r as! HKQuantitySample
let quantity = result.quantity
let count = quantity.doubleValueForUnit(HKUnit(fromString: "count/min"))
println("sample: \(count) : \(result)")
}
}
}
healthKitStore.executeQuery(query)
}
编辑 2:
它工作正常,但我不能像我那样称呼它。所以我在几秒钟后取了它,它工作正常:)
...But as I said earlier, it won't update when the phone is locked...Guess it is some security-thing.
你是对的。
来自HealthKit Framework Reference:
Because the HealthKit store is encrypted, your app cannot read data from the store when the phone is locked. This means your app may not be able to access the store when it is launched in the background. However, apps can still write data to the store, even when the phone is locked. The store temporarily caches the data and saves it to the encrypted store as soon as the phone is unlocked.
如果您希望您的应用在有新结果时收到提醒,您应该查看 Managing Background Delivery:
enableBackgroundDeliveryForType:frequency:withCompletion:
Call this method to register your app for background updates. HealthKit wakes your app whenever new samples of the specified type are saved to the store. Your app is called at most once per time period defined by the specified frequency.