如何通过iOS中的Health Kit通过实时获取心率数据?

时间:2018-12-14 13:36:20

标签: ios watchkit apple-watch watch health-kit

我已经在“观看”中创建了一个会话,并在Health Kit中更新了心率数据。现在,我想在我的iPhone屏幕上显示当前的心率。手表传感器无法从“健康状况”工具箱中获取实时数据,因此会更新“健康状况”工具箱中的“心率数据”,但iPhone应用程序无法正常运行。我已经在以下两种情况下进行了测试。我还记得使用计时器的这种方法/功能,但它没有获取实时数据。

注意:当我打开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()
                }


            }

        }

2 个答案:

答案 0 :(得分:1)

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

在观看代码中:

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秒左右执行一次心率查询,但是如果我理解正确,那么您已经尝试过了,但是没有用。

答案 1 :(得分:0)

这是我自己有关获得附近实时心率的分析。

1。。如果您正在使用iPhone应用程序访问Health Kit数据,则在这种情况下,Health Kit DB不会经常更新/刷新。因此,您的应用无法通过iPhone应用获取实时的最新更新数据。

2。。使用手表应用程序,您可以通过Health Kit DB访问近乎实时的数据。观看应用能够获取实时的最新更新的健康工具包数据。

3。。您需要将数据从手表传输到iPhone应用程序。这是代码供您参考。您可以根据需要编写代码。您只需要通过 HKQuery

访问“心率”
pandas