HealthKit在间隔

时间:2015-05-31 11:04:20

标签: swift health-kit hksamplequery

我在抓住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")
}            

}

但这并没有奏效,因为我发现有一个错误,苹果公司表示它并没有像他们想要的那样工作。猜猜这是一些安全问题。

但后来我想,也许我可以在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

它正在运作,但我无法像我那样称呼它。所以我在几秒钟后取出它并且工作正常:)

1 个答案:

答案 0 :(得分:3)

  

...但正如我之前所说,当手机被锁定时它不会更新......猜猜这是一些安全问题。

你是对的。

来自HealthKit Framework Reference

  

由于HealthKit商店已加密,您的应用无法在手机锁定时从商店读取数据。这意味着您的应用可能无法在后台启动时访问该商店。但是,即使手机处于锁定状态,应用仍然可以将数据写入商店。一旦手机解锁,商店就会临时缓存数据并将其保存到加密存储中。

如果您希望在有新结果时提醒您的应用,则应该查看Managing Background Delivery

  

enableBackgroundDeliveryForType:frequency:withCompletion:

     

调用此方法注册您的应用以获取后台更新。每当指定类型的新样本保存到商店时,HealthKit都会唤醒您的应用程序。根据指定频率定义的每个时间段最多调用一次您的应用。