我想在我的苹果手表上使用Healthkit API,以便在一定间隔内睡觉时安慰我的心跳。
为此,我实现了一个简单的SleepSessionManager类,它负责HKWorkout
的所有设置。它的委托是InterfaceController
,它也拥有该类的实例。我在SleepSessionManager中使用此方法中的流式查询来更新心率:
func createHeartRateStreamingQuery(workoutStartDate: NSDate) -> HKQuery? {
guard let quantityType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate) else { return nil }
let heartRateQuery = HKAnchoredObjectQuery(type: quantityType, predicate: nil, anchor: anchor, limit: Int(HKObjectQueryNoLimit)) { (query, sampleObjects, deletedObjects, newAnchor, error) -> Void in
guard let newAnchor = newAnchor else {return}
self.anchor = newAnchor
self.delegate.heartRateDidChange(sampleObjects)
}
heartRateQuery.updateHandler = {(query, samples, deleteObjects, newAnchor, error) -> Void in
self.anchor = newAnchor!
NSLog("About to update Heartrate")
// InterfaceController
self.delegate.heartRateDidChange(samples)
}
// Will get executed by healthStore
return heartRateQuery
}
然后以这种方式更新我的InterfaceController中的View:
func heartRateDidChange(samples: [HKSample]?) {
NSLog("HeartRate did change")
guard let heartRateSamples = samples as? [HKQuantitySample] else {return}
dispatch_async(dispatch_get_main_queue()) {
guard let sample = heartRateSamples.first else{return}
let value = sample.quantity.doubleValueForUnit(self.sleepSessionManager!.heartRateUnit)
self.label.setText(String(UInt16(value)))
if UInt16(value) > 80 {
// Feedback when heartRate is more than 80 bpm
WKInterfaceDevice.currentDevice().playHaptic(.Notification)
}
}
}
只要界面处于唤醒状态,这种方法就可以正常工作,但是当Watch返回睡眠状态时,它不会再调用heartRateDidChange函数,直到它再次唤醒(控制台中没有打印出任何NSlog)。
我知道,当它处于睡眠状态时我无法调用InterfaceController上的方法,但是不应该运行updateHandler吗?如果您看一下手表,Heartrate-Sensor仍然有效。
由于这是一个专门用于锻炼的API,我想即使手表处于睡眠状态也必须有一种更新我的心率的方法,否则用户必须在锻炼的整个持续时间内观察他的手表以进行测量所有数据。