使用CMPedometer的iWatch准确计算步数
Apple Watch Series 3具有大量传感器,处理速度显着提高,这使其成为功能强大的机器,可以比以前的Watch版本更好地跟踪和评估您的健身数据。
我最近正在研究计步器类型应用程序的实现,在该应用程序中,我必须准确确定iWatch用户采取的步骤。 对于此用例,我决定使用Core Motion框架的CMPedometer。
CMPedometer基本上让您跟踪:
- 步数
- 行驶距离
- 根据爬了多少楼梯的楼层数
- 你走多快或多慢
iWatch跟踪此信息的方式是通过消耗iPhone中集成的加速度计,陀螺仪,磁力计和指南针生成的数据。
CMPedometer是Core Motion框架的一部分,该框架使您可以访问iPhone 5S及更高版本上的内置运动处理器。 它可以处理从集成的加速度计,陀螺仪,磁力计和气压计生成数据(尽管iPhone 6提供了气压计)。 iWatch处理器始终跟踪此数据并临时存储以供使用。 请务必注意,Core Motion只能在任何时间存储当前的7天时间段。
开发健身应用程序的任何人都可以使用Core Motion来同时使用iPhone和iWatch测量运动类型。 除了跑步,散步和骑自行车等常见活动外,iWatch还可以帮助跟踪众多其他户外运动。
CMP计
为了获取步数和有关行进距离的其他详细信息,我使用了计步器对象。 可以使用计步器对象查询历史数据的缓存信息。 除此之外,同一个对象使我们能够在处理数据时获取实时信息。
您可以使用计步器实例来调用以下类型的方法。
- 使用
queryPedometerData(from:to:withHandler:)
获取历史数据 - 使用
startUpdates(from:withHandler:)
放置观察者实时更新
让我们开始一个演示计算步骤,距离和楼层数(爬楼梯)的演示。 但是,让我们先谈谈隐私!
CMPedometer更具体地使用了Apple认为私有数据的几种动作 。 在计步器上,您还将使用位置数据,因此隐私是一个更大的问题。 开发人员需要在info.plist中添加密钥NSMotionUsageDescription
来征求用户的许可。 您可以在plist中添加密钥,如下所示:
步骤1:导入Core Motion
您需要先导入核心运动才能使用CMPedometer。
//导入CoreMotion
导入CoreMotion
步骤#2:创建CMPedometer的实例
让我们创建CMPedometer实例并需要变量
// MARK:-变量
fileprivate let计步器= CMPedometer()
fileprivate var startDate:日期? =无
fileprivate var timeElapsed:TimeInterval = 1.0
fileprivate var numberOfSteps:Int! = 0
fileprivate var distance:Double! = 0.0
fileprivate var步伐:翻倍! = 0.0
fileprivate var averagePace:Double! = 0.0
Fileprivate var FloorsAscended:整数! = 0
Fileprivate var FloorsDscended:Int! = 0
fileprivate var cadence:Double! = 0
步骤#3:检查数据是否可用
在使用计步器数据之前,我们需要检查该数据是否在当前设备中可用?
///检查步骤计数在设备中是否可用
var isStepCountingAvailable:布尔{
得到{
返回CMPedometer.isStepCountingAvailable()
}
}
///检查设备中的步速是否可用
var isPaceAvailable:布尔{
得到{
返回CMPedometer.isPaceAvailable()
}
}
///检查距离是否在设备中可用
var isDistanceAvailable:布尔{
得到{
返回CMPedometer.isDistanceAvailable()
}
}
var isCadenceAvailable:布尔{
得到{
返回CMPedometer.isCadenceAvailable()
}
}
///检查楼层数是否在设备中可用
var isFloorCountingAvailable:布尔{
得到{
返回CMPedometer.isFloorCountingAvailable()
}
}
让我们为此演示设置一个基本的UI。 像这样:
步骤#4:连接渠道和行动
并连接上述标签和按钮的插座和操作。
//标记:-IBOutlets
@IBOutlet var lblTime:WKInterfaceLabel!
@IBOutlet var lblSteps:WKInterfaceLabel!
@IBOutlet var lblCadence:WKInterfaceLabel!
@IBOutlet var lblPace:WKInterfaceLabel!
@IBOutlet var lblAvgPace:WKInterfaceLabel!
@IBOutlet var lblDistance:WKInterfaceLabel!
@IBOutlet var lblFloorsUp:WKInterfaceLabel!
@IBOutlet var lblFloorsDown:WKInterfaceLabel!
@IBOutlet var btnStartUpdating:WKInterfaceButton!
var startDate:日期?
//标记:-动作方法
@IBAction func btnStartClicked(){
}
步骤5:检查授权状态
现在,让我们开始观察步骤。 因此,在确定计步器的可用性之后,我们需要检查CMPedometer的授权状态。
私有函数checkAuthorizationStatus()-> Bool {
var pedoMeterAuthorized = false
开关CMPedometer.authorizationStatus(){
大小写被拒绝:
onStop()
case .authorized:pedoMeterAuthorized = true
默认值:break
}
返回pedoMeterAuthorized
}
我们差不多完成了,让我们从block开始观察者。
公共变量stepCountingHandler:((( ?
私人功能startTrackingSteps(){
pedometer.startUpdates(from:Date(),withHandler:
{(pedometerData,error)in
如果让pedData = pedometerData {
self.setPedometerData(pedData:pedData)
如果self.stepsCountingHandler!=无
{
self.stepsCountingHandler?(self.numberOfSteps,self.distance,self.averagePace,self.pace,self.floorsAscended,self.floorsDscended,self.cadence,Date()。secondsInBetweenDate(self.startDate))
}
}其他{
self.numberOfSteps =无
}
})
}
私人功能setPedometerData(pedData:CMPedometerData)
{
self.numberOfSteps = Int(截断:pedData.numberOfSteps)
如果让distancee = pedData.distance {
self.distance = Double(截断:distancee)
}
如果让averageActivePace = pedData.averageActivePace {
self.averagePace = Double(截断:averageActivePace)
}
如果让currentPace = pedData.currentPace {
self.pace = Double(截断:currentPace)
}
如果让floor = pedData.floorsAscended {
self.floorsAscended = Int(截断:floor)
}
如果让floor = pedData.floorsDescended {
self.floorsDscended = Int(截断:floor)
}
如果让cadence = pedData.currentCadence {
self.cadence = Double(截断:节奏)
}
}
在接口控制器上添加处理程序,以便我们可以在那里绑定数据。
activityHelper.stepsCountingHandler = {步距,距离,
平均步伐,步伐,楼层升序,楼层Dscended,节奏,
时间在
self.lblSteps.setText(“ Steps:\(steps”“)
self.lblDistance.setText(“ Distance:\(distance)”)
self.lblAvgPace.setText(“ Avg Pace:\(averagePace)”)
self.lblPace.setText(“ Pace:\(pace)”)
self.lblCadence.setText(“ Cadence:\(cadence)”)
self.lblFloorsUp.setText(“节奏:\(floorsAscended)”)
self.lblFloorsDown.setText(“节奏:\(floorsDscended)”)
self.lblTime.setText(“时间:\(timeElapsed)秒”)
}
步骤6:获取历史计步器数据
activityHelper.getStepsDataFor(startDate:startDate,
endDate:endDate,
successBlock:{
(步数,距离,平均步速,步速,地板升序,地板Dscended,节奏,经过的时间)
self.lblSteps.setText(“ Steps:\(steps”“)
self.lblDistance.setText(“ Distance:\(distance)”)
self.lblAvgPace.setText(“ Avg Pace:\(averagePace)”)
self.lblPace.setText(“ Pace:\(pace)”)
self.lblCadence.setText(“ Cadence:\(cadence)”)
self.lblFloorsUp.setText(“节奏:\(floorsAscended)”)
self.lblFloorsDown.setText(“节奏:\(floorsDscended)”)
self.lblTime.setText(“时间:\(timeElapsed)秒”)
},errorBlock:{(错误)在
})
这就是最终结果的样子。 😎
计步器是“核心运动”的高级对象。 它设置自己的刷新率,我们可以通过闭包获取更新,因此它是按自己的时间表进行的,而不是我们可以控制的。 您可以从此处下载完整代码。