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 будит ваше приложение всякий раз, когда новые образцы указанного типа сохраняются в магазине. Ваше приложение вызывается не чаще одного раза за период времени, определенный указанной частотой.

Другие вопросы по тегам