心率测试可以算是apple watch的一个很大的特性,很多健康或者运动类app都会用到心率相关功能,这篇文章我们就来讲讲在watch OS2中心率开发的一些知识点,全文将使用swift进行描述。
导入头文件、声明变量
- 我们要做的第一步当然是导入头文件:
import HealthKit
我们接下来要用到的所有api都在这个头文件里。
- 声明一个workOut变量
self.workoutSession = HKWorkoutSession(activityType: HKWorkoutActivityType.CrossTraining, locationType: HKWorkoutSessionLocationType.Indoor)
self.workoutSession?.delegate = self
这个变量中有两个参数
/*!
@method initWithActivityType:locationType:
@param activityType The activity type of the workout session.
@param locationType The type of location where the workout will be performed.
*/
public init(activityType: HKWorkoutActivityType, locationType: HKWorkoutSessionLocationType)
第一个参数选择活动的类型、第二个参数选择活动的地点。
(其实我并不清楚选择不同的参数对我们的结果有什么影响,也许是苹果在不同的参数下选择了不同的算法)
HKWorkoutSessionDelegate中有两个方法需要我们来实现,第一个是活动启动失败的回调,第二个就是活动状态发生变化。
func workoutSession(workoutSession: HKWorkoutSession, didChangeToState toState: HKWorkoutSessionState, fromState: HKWorkoutSessionState, date: NSDate){
switch toState {
case .Running:
workoutDidStart()
break
case .Ended: break
// workoutDidEnd(date)
default:
print("Unexpected state \(toState)")
}
}
func workoutSession(workoutSession: HKWorkoutSession, didFailWithError error: NSError){
print(error)
print("workout fail")
}
我们在活动启动成功以后开始查询心率。
(启动成功以后我们的手表表低将发出蓝光,使用光电进行心率测试)
- 使用HKHealthStore启动活动
let healthStore = HKHealthStore()
let quantityType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)//指定活动类型
let dataTypes = Set(arrayLiteral: self.quantityType!)
self.healthStore.requestAuthorizationToShareTypes(nil, readTypes: dataTypes) { (success, error) in
}
healthStore.startWorkoutSession(self.workoutSession!)
在这里我们使用quantityType来指定我们的活动类型。
我们已经成功的启动了我们的活动,如果启动成功或者失败,将在workoutSession的回掉中反馈给你。
- 活动启动成功,查询心率
当我们的活动启动成功以后,手表将读取到的心率保存到手机端的“健康”当中,我们需要对健康中的数据进行查询;
let predicate = HKQuery.predicateForSamplesWithStartDate(NSDate(), endDate: nil, options: .None)
let anchor = HKQueryAnchor(fromValue: Int(HKAnchoredObjectQueryNoAnchor))
func workoutDidStart(){
let heartRateQuery = HKAnchoredObjectQuery(type: quantityType!, predicate: predicate, anchor: anchor, limit: HKObjectQueryNoLimit) { (query, Sample, deletedObjects, newAnchor, error) in
print(error)
if Sample != nil{
print("start:"+(Sample?.description)!)
}
}
heartRateQuery.updateHandler = {(AnchoredObjectQuery:HKAnchoredObjectQuery, Sample:[HKSample]?, DeletedObject:[HKDeletedObject]?, Anchor:HKQueryAnchor?, error:NSError?) -> Void in
print("update:"+(Sample?.description)!)
}
healthStore.executeQuery(heartRateQuery)
}
这段代码非常好理解,我们声明了一些查询的变量,然后使用 healthStore对心率进行了查询,巴拉巴拉~~~
授权
我们信心慢慢的启动了应用,掷地有声的表明代码绝对没有问题,然后还是出现了问题,XCode抛出了一个错误:
Error occurred = Error Domain=com.apple.healthkit Code=4 "Missing com.apple.developer.healthkit entitlement." UserInfo=0x7fa748534b00 {NSLocalizedDescription=Missing com.apple.developer.healthkit entitlement.}
我们要知道苹果对隐私是十分关注的,而健康数据则是重中之重,所以苹果对这方面的权限十分关注,以上这个报错是因为我们缺少了开启心率记录的权限,解决方法如下图:
我们将healthKit的开关打开,这样我们就有调用healthKit相关api的能力了。
我们满心以为现在代码没有问题了,再次启动应用,然而却还是报错了:
这个报错是因为我们想要查询健康中的数据,却没有进行授权,所以我们需要在iPhone端进行授权:
我们在iPhone的delegate中加入以下代码:
func applicationShouldRequestHealthAuthorization(application: UIApplication) {
let healthStore = HKHealthStore()
self.healthStore.handleAuthorizationForExtensionWithCompletion { success, error in
}
}
这段代码将对健康数据读取进行授权,启动应用,将提示我们在iPhone端进行授权,来带iPhone端则是会打开健康授权界面,这时候我们允许读取心率即可。
现在再启动应用,我们终于读取到了心率数据,数据将在 heartRateQuery的回调中返回,回掉中有一个参数是[HKSample]?在这个参数中我们可以读取到我们的心率数值,像这样
let heartRateUnit = HKUnit(fromString: "count/min")
guard let sample = heartRateSamples.first else{return}
let value = sample.quantity.doubleValueForUnit(self.heartRateUnit)
停止心率测试
停止心率测试和进行心率查询基本类似,还是同样的变量,这里不再重复声明:
healthStore.stopQuery(p.p1 {heartRateQuery)
以上则是进行心率测试的基本内容。
更多文章请关注我的博客:StrongX.cn