首页 > 解决方案 > 在后台获取苹果健康数据

问题描述

我想在后台从苹果健康中获取数据。我不知道在哪里调用我的函数 updateOnBackground

我查看了相关主题,目前有这个:

 func updateOnBackground() {
        
        let quantityType = HKQuantityType.quantityType(forIdentifier: .heartRate)!
        self.healthStore.enableBackgroundDelivery(for: quantityType, frequency: .immediate) { (success, error) in
            if let error = error {
                print("\(error)")
            }
            if success {
                print("background delivery enabled")
            }
        }
        
        let query = HKObserverQuery(sampleType: quantityType, predicate: nil) { (query, completionHandler, error) in
            self.updateData(){
                completionHandler()
            }
        }
        healthStore.execute(query)
        
    }

这是在应用程序处于活动状态时获取数据的功能:

 class func getMostRecentSample(for sampleType: HKSampleType,
                                   completion: @escaping (HKQuantitySample?, Error?) -> Swift.Void) {
        let mostRecentPredicate = HKQuery.predicateForSamples(withStart: Date.distantPast, end: Date(), options: .strictEndDate)
        let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: false)
        let limit = 1
        let sampleQuery = HKSampleQuery(sampleType: sampleType, predicate: mostRecentPredicate, limit: limit, sortDescriptors: [sortDescriptor]) { (query, samples, error) in
            DispatchQueue.main.async {
                guard let samples = samples,
                    
                    let mostRecentSample = samples.first as? HKQuantitySample else {
                        completion(nil, error)
                        
                        return
                }
                //print(samples)
                completion(mostRecentSample, nil)
            }
            
        }
        
        HKHealthStore().execute(sampleQuery)
    }
    func updateData(completionHandler: @escaping () -> Void) {
        let sampleType =  HKQuantityType.quantityType(forIdentifier: .heartRate)!
        HealthData.getMostRecentSample(for: sampleType) { (sample, error) in
            self.handleNewData(new: sample!)
            completionHandler()
        }
    }
    
    func handleNewData(new: HKQuantitySample) {
        print(new)
        
    }

我认为这里不需要函数 getMostRecentSample,否则我还能做得更好吗?

标签: iosswifthealthkit

解决方案


对于观察查询和后台交付,根据 Apple 文档https://developer.apple.com/documentation/healthkit/hkhealthstore/1614175-enablebackgrounddelivery,没有比在 AppDelegate.swift 中更好的地方了

func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
    updateOnBackground()
    return true
}

这将保证您的应用会收到来自 Apple Health 的通知,告知您新数据已生成。对于某些类型,更新频率可能不同。例如,如果您尝试以 .immediate 频率获取步骤,这将不起作用 - 它只会在一小时后发生(由 Apple Health App 自动决定)。

你可以试试我的 CocoaPod。这是链接:https ://cocoapods.org/pods/HealthKitReporter 。它是 HealthKit 框架之上的一个包装器,用于简化读/写操作 + 观察。

您还可以查看 HKAnchoredObjectQuery implementation(也可以在 pod 中)。它就像一个观察者查询 + 示例查询,也是一个长时间运行的查询。看看这里https://developer.apple.com/documentation/healthkit/hkanchoredobjectquery


推荐阅读