HealthKit 在间隔之间获取数据

Posted

技术标签:

【中文标题】HealthKit 在间隔之间获取数据【英文标题】:HealthKit fetch data between interval 【发布时间】:2015-05-31 11:04:19 【问题描述】:

我在掌握 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 中获得了一些值。

编辑:

好的,我试过了,它有时会起作用,但并非总是如此。有人有想法吗?

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

它正在工作,但我不能像以前那样称呼它。所以几秒钟后我拿了它,它工作得很好:)

【问题讨论】:

您是否将此代码放入您的 AppDelegate 中?我试图让观察者工作,但无论我输入什么类型,它都不会让我知道添加或删除了某些内容:(。 【参考方案1】:

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

你是对的。

来自HealthKit Framework Reference:

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

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

enableBackgroundDeliveryForType:frequency:withCompletion:

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

【讨论】:

以上是关于HealthKit 在间隔之间获取数据的主要内容,如果未能解决你的问题,请参考以下文章

如何仅查询 HealthKit 以获取给定日期的总“在床上”时间?

如何使用 HealthKit 从 iHealth 获取元数据?

如何使用 HealthKit 从 iHealth 获取元数据?

如何从 HealthKit 获取元数据?

如何使用 HealthKit 从特定日期准确获取 24 小时的睡眠数据?

如何使用 HealthKit 从特定日期准确获取 24 小时的睡眠数据?