我在 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/