apple watch心率测试的那点事儿

心率测试可以算是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.}

我们要知道苹果对隐私是十分关注的,而健康数据则是重中之重,所以苹果对这方面的权限十分关注,以上这个报错是因为我们缺少了开启心率记录的权限,解决方法如下图:

apple watch心率测试的那点事儿_第1张图片
Paste_Image.png

我们将healthKit的开关打开,这样我们就有调用healthKit相关api的能力了。

我们满心以为现在代码没有问题了,再次启动应用,然而却还是报错了:

Paste_Image.png

这个报错是因为我们想要查询健康中的数据,却没有进行授权,所以我们需要在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

你可能感兴趣的:(apple watch心率测试的那点事儿)