2015-05-31 4 views
2

У меня есть небольшая проблема, захватывающая 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) 

Но когда я попытался это ничего не нашел. Возможно, у меня все это не так ...

Я использую монитор сердечного ритма на груди, и я знаю, что получаю некоторые значения в healthKit в начале и в конце.

Edit:

Хорошо, я попробовал его и он работает несколько раз, не всегда. У кого-то есть идея?

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) 
} 

Edit 2:

Он работал, но я не мог назвать его так, как я и сделал. Так что я принес его на пару секунд позже, и она работала отлично :)

+0

Вы помещаете этот код в свой AppDelegate? Я пытаюсь заставить наблюдателя работать, но независимо от того, какой тип я вставляю, он никогда не дает мне знать, что что-то было добавлено или удалено :(. –

ответ

3

... Но, как я уже говорил ранее, он не будет обновляться, когда телефон заблокирован ... Предполагаю, что некоторые безопасности- вещь.

Вы верны.

От HealthKit Framework Reference:

Поскольку HealthKit магазин зашифрован, ваше приложение не может прочитать данные из магазина, когда телефон заблокирован. Это означает, что ваше приложение не сможет получить доступ к хранилищу при его запуске в фоновом режиме. Однако приложения могут записывать данные в магазин, даже если телефон заблокирован. Хранилище временно кэширует данные и сохраняет их в зашифрованном хранилище, как только телефон разблокируется.

Если вы хотите, чтобы ваше приложение, чтобы получить извещение, когда есть новые результаты, вы должны рассмотреть Managing Background Delivery:

enableBackgroundDeliveryForType:frequency:withCompletion:

Вызов этот метод, чтобы зарегистрировать ваше приложение для обновления фона. HealthKit пробуждает ваше приложение, когда новые образцы указанного типа сохраняются в хранилище. Ваше приложение вызывается не более одного раза за период времени, определенный указанной частотой.

Смежные вопросы