0

我关注了Apple Docs和 Stackoverflow 上的几个线程,了解如何实现从 Health Store 后台获取数据。到目前为止,我有:

  • 向我的 appID添加了 HealthKit 权利
  • 添加了所需的背景模式
  • 按照 Apple 的建议将代码添加到AppDelegate.swift (下面的代码片段不遵循 OOP 只是为了方便在此处说明

这是我的代码(swift):如果您的答案在 Obj-C 中并且有效,请同时说明,我将不得不翻译它,但这没问题。

AppDelegate.swift

var healthStore: HKHealthStore?
var bpmSamples: [HKQuantitySample]?

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    let dataTypesToWrite = [ ]
    let dataTypesToRead = [
        HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate),
        HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBodyMassIndex),
        HKCharacteristicType.characteristicTypeForIdentifier(HKCharacteristicTypeIdentifierDateOfBirth)
    ]
    if self.healthStore == nil {
        self.healthStore = HKHealthStore()
    }
    self.healthStore?.requestAuthorizationToShareTypes(NSSet(array: dataTypesToWrite as [AnyObject]) as Set<NSObject>,
        readTypes: NSSet(array: dataTypesToRead) as Set<NSObject>, completion: {
            (success, error) in
            if success {
                self.addQueryObserver()
                println("User completed authorisation request.")
            } else {
                println("The user cancelled the authorisation request. \(error)")
            }
    })
    return true
}

func addQueryObserver(){
    let sampleType =
    HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)

    let query = HKObserverQuery(sampleType: sampleType, predicate: nil) {
        query, completionHandler, error in
        if error != nil {
            // Perform Proper Error Handling Here...
            println("*** An error occured while setting up the stepCount observer. \(error.localizedDescription) ***")
            abort()
        }
        println("query is running")

        self.performQueryForHeartBeatSamples()
        completionHandler()
    }
    healthStore?.executeQuery(query)
    healthStore?.enableBackgroundDeliveryForType(sampleType, frequency:.Immediate, withCompletion:{
        (success:Bool, error:NSError!) -> Void in
        let authorized = self.healthStore!.authorizationStatusForType(sampleType)
        println("HEALTH callback success", success)
        println("HEALTH callback authorized", sampleType)
    })
    if HKHealthStore.isHealthDataAvailable() == false {
        println("HEALTH data not available")
        return
    } else {
        println("HEALTH OK")
        self.performQueryForHeartBeatSamples()
    }
}
 // MARK: - HealthStore utility methods
func performQueryForHeartBeatSamples() {
    let endDate = NSDate()
    let startDate = NSCalendar.currentCalendar().dateByAddingUnit(.CalendarUnitMonth, value: -2, toDate: endDate, options: nil)

    var heartRate : HKQuantityType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)

    let predicate = HKQuery.predicateForSamplesWithStartDate(startDate, endDate: endDate, options: .None)
    let query = HKSampleQuery(sampleType: heartRate, predicate: predicate, limit: 0, sortDescriptors: nil, resultsHandler: {
        (query, results, error) in
        if results == nil {
            println("There was an error running the query: \(error)")
        }
        dispatch_async(dispatch_get_main_queue()) {
            self.bpmSamples = results as? [HKQuantitySample]
            let heartRateUnit: HKUnit = HKUnit.countUnit().unitDividedByUnit(HKUnit.minuteUnit())
            if self.bpmSamples?.count > 0 {
                if let sample = self.bpmSamples?[self.bpmSamples!.count - 1] {
                    println(sample.quantity!.description)
                    let quantity = sample.quantity
                    var value = quantity.doubleValueForUnit(heartRateUnit)
                    println("bpm: \(value)")
                }
            }
            else {
                println("No Data")
            }
        }
    })
    self.healthStore?.executeQuery(query)
}

所以,问题是我只有在我手动将应用程序从后台恢复到活动状态时才会收到更新。HKObserverQuery在后台模式下似乎对我不起作用。

有什么建议么?

4

1 回答 1

1

根据我的经验,频率“.Immediate”效果不佳。查询处理程序被插入后台队列。如果频繁添加匹配样本或 iOS 繁忙,则立即频率无法正常工作。

此外,您不能使用HKSampleQueryin HKObserverQueryupdateHandlerofHKObserverQuery可能会起作用,但resultHandlerof HKSampleQuerywill 不会。观察者查询的处理程序可以在后台模式下执行,但示例查询之一不能在后台模式下执行。

你应该知道ONLY HKObserverQuery可以在后台使用

于 2015-10-17T02:52:45.477 回答