ios - 如何从 iOS 中的 Healthkit 实时获取心率数据?

标签 ios watchkit apple-watch watch healthkit

我在 Watch 中创建了一个 session 并更新了 Health Kit 中的心率数据。现在,我想在我的 iPhone 屏幕上显示当前的心率。 watch 传感器更新 Health kit 中的心率数据,但 iPhone 应用程序无法从 Health kit 中获取实时数据。我已经测试了以下两种情况。我还记得使用计时器使用此方法/函数,但它没有获取实时数据。

注意:当我打开 Health App 并重新打开我的应用程序时,它会自动刷新数据。如果我的应用程序一直在前台,那么下面的代码不会刷新健康工具包中的最新数据

<强>1。尝试使用 HKSampleQuery 获取实时心率数据

        let calendar = NSCalendar.current
        let components = calendar.dateComponents([.year, .month, .day], from: Date())
        let startDate : NSDate = calendar.date(from: components)! as NSDate
        let endDate : Date = calendar.date(byAdding: Calendar.Component.day, value: 1, to: startDate as Date)!

        let predicate = HKQuery.predicateForSamples(withStart: startDate as Date, end: endDate, options:[])

        //descriptor
        let sortDescriptors = [NSSortDescriptor(key: HKSampleSortIdentifierEndDate, ascending: false)]

        self.heartRateQuery = HKSampleQuery(sampleType: self.heartRateType, predicate: predicate, limit: 1, sortDescriptors: sortDescriptors, resultsHandler: { (query:HKSampleQuery,  results:[HKSample]?, error:Error?) in

            guard error == nil else { print("error in getting data"); return }

            self.collectCurrentHeartRateSample(currentSampleTyple: results)

        })

        self.healthStore.execute(self.heartRateQuery!)

<强>2。尝试使用 HKAnchoredObjectQuery 获取实时心率数据

    let sampleType : HKSampleType =  HKObjectType.quantityType(forIdentifier: HKQuantityTypeIdentifier.heartRate)!
    let predicate : NSPredicate =  HKQuery.predicateForSamples(withStart: startDate as Date, end: endDate, options: [])
    let anchor: HKQueryAnchor = HKQueryAnchor(fromValue: 0)

    let anchoredQuery = HKAnchoredObjectQuery(type: sampleType, predicate: predicate, anchor: anchor, limit: HKObjectQueryNoLimit) { (query, samples, deletedObjects, anchor, error ) in

        self.collectCurrentHeartRateSample(currentSampleTyple: samples!, deleted: deletedObjects!)

    }

    anchoredQuery.updateHandler = { (query, samples, deletedObjects, anchor, error) -> Void in
        self.collectCurrentHeartRateSample(currentSampleTyple: samples!, deleted: deletedObjects!)
    }

    self.healthStore.execute(anchoredQuery)

=============================================

解析数据

func collectCurrentHeartRateSample(currentSampleTyple : [HKSample]?, deleted : 

    [HKDeletedObject]?){

    //    func collectCurrentHeartRateSample(currentSampleTyple : [HKSample]?){

            DispatchQueue.main.async {

                self.currentHeartRateSample = currentSampleTyple

                //Get Last Sample of Heart Rate
                self.currentHeartLastSample = self.currentHeartRateSample?.last
                print("lastSample : \(String(describing: self.currentHeartLastSample))")

                if self.currentHeartLastSample != nil {

                    let result = self.currentHeartLastSample as! HKQuantitySample

                    let heartRateBPM = result.quantity.doubleValue(for: HKUnit(from: "count/min"))
                    let heartRateBPMUnit = "count/min"

                    let deviceUUID = self.currentHeartLastSample?.uuid
                    let deviceIdentity = result.sourceRevision.source.name
                    let deviceProductName = self.currentHeartLastSample?.device?.name
                    let deviceProductType = result.sourceRevision.productType
                    let deviceOSVersion = result.sourceRevision.version

                    let startDate = self.currentHeartLastSample?.startDate
                    let endDate = self.currentHeartLastSample?.endDate

                    self.aCollectionView.reloadData()
                }


            }

        }

最佳答案

我认为最好的方法是使用 Watch Communication 将心率数据简单地发送到手机应用程序。

在 watch 代码中:

func send(heartRate: Int) {
    guard WCSession.default.isReachable else {
        print("Phone is not reachable")
        return
    }

    WCSession.default.sendMessage(["Heart Rate" : heartRate], replyHandler: nil) { error in
        print("Error sending message to phone: \(error.localizedDescription)")
    }
 }

在手机上,您通过以下方式接收数据:

func session(_ session: WCSession, didReceiveMessage message: [String: Any]) {
    if let heartRate = message["Heart Rate"] {
        print("Received heart rate: \(heartRate)")
    } else {
        print("Did not receive heart rate =[")
    }
}

这应该几乎是实时发生的。或者,还有另一种不太可靠的解决方案 (imo),即每 5 秒左右执行一次心率查询,但如果我理解正确的话,你已经尝试过但没有成功。

关于ios - 如何从 iOS 中的 Healthkit 实时获取心率数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53780808/

相关文章:

ios - avplayer 没有播放 URL

ios - 如何使用 Watchkit 进行异步操作(GPS + API 调用)和

ios - undefined symbol : _OBJC_CLASS_$_WKInterfaceController error after updating Xcode to version 11. 1

ios - WatchKit 通知标题颜色

ios - 停止在 UITableViewCell 中重复值

ios - 使用 ApI 在 ios 中阻止用户 in instagram

performance - 更新复杂功能会逐渐降低 watchOS3 中 Apple Watch 应用程序的性能

ios - 未从 WatchApp Target 获取存储的 UIImage

watchkit - 如何让 HKworkoutsession 始终成为活跃的锻炼类(class)

ios - 如何从我的 iphone 为我的应用程序浏览 pdf 文件,就像我能够通过 ibooks 浏览 pdf 文件一样?