HealthKit выбирает данные между интервалами
У меня есть небольшая проблема с захватом HealthKit. Я хочу получить частоту сердечных сокращений от HealthKit с определенным временем. Я делал это в прошлом (пока не заметил, что не могу получить данные, когда телефон заблокирован)
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. Но, как я сказал ранее, он не будет обновляться, когда телефон заблокирован. Я пытался с помощью:
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)
Но когда я попробовал, ничего не нашел. Может быть, я все неправильно понял...
Я использую пульсометр на своей груди, и я знаю, что я получаю некоторые значения в аптечке в течение начального и конечного времени.
Редактировать:
Хорошо, я попробовал это, и это работает несколько раз, не всегда. У кого-то есть идея?
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:
Это работало, но я не мог назвать это так, как я. Таким образом, я получил это пару секунд спустя, и это работало отлично:)
1 ответ
... Но, как я уже говорил ранее, он не будет обновляться, когда телефон заблокирован... Думаю, это какая-то проблема безопасности.
Ты прав.
Из ссылки на HealthKit Framework:
Поскольку хранилище HealthKit зашифровано, ваше приложение не может читать данные из хранилища, когда телефон заблокирован. Это означает, что ваше приложение может не иметь доступа к магазину, когда оно запускается в фоновом режиме. Тем не менее, приложения могут записывать данные в магазин, даже если телефон заблокирован. Хранилище временно кэширует данные и сохраняет их в зашифрованном хранилище, как только телефон разблокирован.
Если вы хотите, чтобы ваше приложение уведомлялось о появлении новых результатов, вам следует ознакомиться с разделом Управление фоновой доставкой:
enableBackgroundDeliveryForType:frequency:withCompletion:
Вызовите этот метод, чтобы зарегистрировать свое приложение для фоновых обновлений. HealthKit будит ваше приложение всякий раз, когда новые образцы указанного типа сохраняются в магазине. Ваше приложение вызывается не чаще одного раза за период времени, определенный указанной частотой.