美文网首页iOS加速计,计步功能
iOS中计步器的实现方案及原理

iOS中计步器的实现方案及原理

作者: a乾坤大挪移a | 来源:发表于2019-03-20 19:39 被阅读0次

    前言

    当前社会随着社会水平的越来越高,人民饮食也更加的丰富多样,随之而来就成就了越来越多可爱的胖子。胖子多了,一些“不良商贩”发现商机研发出了运动健身类的APP,如:Keep,咕咚,动动,趣走等等,就连我们的移动社交老大哥腾讯也相继推出了微信运动,qq运动等功能。那么今天我将通过此篇文章来给大家简单介绍一下在我们的iOS中想要实现一个计步器的功能有哪几种方案,以及实现它的一些原理。

    实现方案

    从目前技术角度来看,ios实现计步功能主要有三种方案:加速计,CMPedometer,HealthKit。下面我们分别来说说这三种实现方案。

    一、加速计

    iOS4以后苹果已经提供了CoreMotion(核心运动框架),但是并没有提供给我们关于步数计算和行走公里数的计算方法。iOS7出现以后苹果在CoreMotion中添加了CMStepCounter,此时我们就可以通过CMStepCounter来计算行走的步数和公里数据了。iOS8的时候又出现了CMPedometer,它是CMStepCounter的替代者,CMPedometer中的数据种类也变得更加多样,比如我们不只可以获取步数和公里数,我们还可以计算我们的上下楼层数,以及我们活动的平均速度等等。但是由于硬件的缘故,在iPhone5s以下的设备中没有协处理器,就设备本身来讲我们是无法通过手机去计算步数和公里数的。难道这样我们就放弃了我们要做计步器的初衷了吗?当然不是,下面我们就来介绍在iPhone5s以下设备中比较流行的一种计步器的实现方案——加速计

    加速计是CoreMotion框架中用来计算设备在三维空间中的加速度的。那么我们如何通过加速计来计算步数呢?接下来我将详细介绍加速计计算步数的原理。

    原理

    我们通过加速计来进行特性分析,分别用以检测人步行中三个方向的加速度变化,如下图

    当我们在水平步行运动中,垂直和前进两个加速度会呈现周期性变化,如图下图所示,在步行收脚的动作中,由于重心向上单只脚触地,垂直方向加速度是呈正向增加的趋势,之后继续向前,重心下移两脚触底,加速度相反。水平加速度在收脚时减小,在迈步时增加。

    反映到图表中,我们可以看到在步行运动中,垂直和前进产生的加速度与时间大致为一个正弦曲线,而且在某点有一个峰值,其中垂直方向的加速度变化最大,通过对轨迹的峰值进行检测计算和加速度阈值决策,即可实时计算用户运动的步数。

     因为用户在运动中可能手平持设备或者将设备置于口袋中,所以设备的放置方向不定,为此我们通过计算三个加速度的矢量长度,获得一条步行运动的正弦曲线轨迹。

      第二步是峰值检测,我们记录了上次矢量长度和运动方向,通过矢量长度的变化,可以判断目前加速度的方向,并和上一次保存的加速度方向进行比较,如果是相反的,即是刚过峰值状态,则进入计步逻辑进行计步,否则舍弃。通过对峰值的次数累加可得到用户步行步伐。

      最后是去多余的干扰,手持设备会有一些低幅度和快速的移动状态,或是我们说的手抖和快速甩动,或者某个恶作剧用户想通过短时快速反复摇动设备来模拟人走路(当然也包括哪些将手机捆绑在狗尾巴上的天才),这些干扰数据如果不剔除,会影响记步的准确值,对于这种干扰,我们可以通过给检测加上阈值和步频判断来过滤。比如我们可以设置一个一步所用的时间,如果短于这个时间我们就过滤掉。就像博尔特,100米最快也需要9.69s。如果有生物跑100米所用时间小于8秒了,按照现在的身体极限我们就可以断定这个生物99.9%不是人类。

    二、CMPedometer

    iOS8以后,CoreMotion框架中为我们提供了一个获取用户活动信息的对象CMPedometer,通过CMPedometer我们可以获取用户的活动信息,如:行走步数,行走的公里数,上下楼层数以及平均速度等。因此我们通过CMPedometer调用它的API接口就完全可以获取到我们想要的步数。下边我将介绍一下我们用到的API。

    1. 当我们在使用CMPedometer查询我们需要的数据的时候,比如:步数,公里数,上下楼层数等,我们需要先通过判断接口判断设备中的这些功能是否可用,如下边方法:

    //判断计步器是否可用

    + (BOOL)isStepCountingAvailable;

    //是否支持距离估计

    + (BOOL)isDistanceAvailable;

    //是否支持楼梯计数

    + (BOOL)isFloorCountingAvailable;

    //等等,不一一进行介绍了。

     2. 因为我们需要从设备中获取我们需要的活动数据,所以我们需要调用的是设备的数据查询接口,如下边方法:

    //此方法是从某一时间段开始,连续的采集数据,当设备中的活动数据发生变更就会回调此方法,此方法是在串行队列中执行。

    -(void)startPedometerUpdatesFromDate:(NSDate*)start withHandler:(CMPedometerHandler)handler;

    //此方法是查询某一时间段的数据,时间可长达7天,此方法是在串行队列中执行。

    - (void)queryPedometerDataFromDate:(NSDate*)start toDate:(NSDate*)endwithHandler:(CMPedometerHandler)handler;

    3. 废话不多说,直接上代码 

    连续获取数据

     获取某一时间段的数据

    更新UI

    三、HealthKit

           iOS8以后苹果推出了一个新的手机自带的App——健康App,这个App就是用来显示我们的活动信息的。并且苹果还为我们提供了一个访问健康App的框架HealthKit。我们可以理解HealthKit是一个活动数据的中央存储库,而健康App是用来展示这个库中的数据的。那么HealthKit是如何获取用户的活动数据的呢?首先我们想一下,健康App中的运动数据是从哪儿来的?运动信息嘛当然是从核心运动框架里边来的了,那么访问核心运动框架中的信息都是通过CMPedometer来访问的,所以我们就知道了HealthKit底层也是通过上边我们提到CMPedometer来获取用户信息的,只不过它的获取方法在手机内部,通过协处理器来进行计算的。而协处理器在5s以后的设备中才出现的,所以在5s以前的设备中是无法获取用户的运动信息的。

      

    我们在使用HealthKit的时候的注意事项:

    A:需要把HealthKit配置到AppID中

    B:Xocede中需要打开HealthKit的开关选项

    C:需要调用isHealthDataAvailable方法检测HealthKit是否可用

    D:在读取和写入数据之前需要先获取权限,并且设置读取和写入的数据类型

    申请权限

    F:在info.plist文件中,增加NSHealthShareUsageDescription用于读取数据的描述和NSHealthUpdateUsageDescription用于写入数据的描述。

    设置好上面的配置信息后我们如何访问和读取数据呢,下边我们将以特征数据(性别)和样本数据(步数)为例,话不多说,直接上代码。

    性别读取:

    特征数据我们一般都是用HKHealthStore直接访问,返回一个性别类型对象,然后通过对象值判断性别。

     注意:特征数据只能读取不能写入,如何修改的话只能通过健康App来修改

    步数读取:

    a:事例查询

    此查询方式为事例查询,可以查询到每一条写入的数据,并且能可以获取数据的来源,通过来源可以分析数据是设备背身记录的数据还是三方app写入的数据。

    b:统计查询

    此查询方式为统计查询,查询结果为步数的总和,不区分数据来源。

    步数写入:

    写入数据一般我们采用saveObject的形式

    以上为三种实现计步器的实现方案,下边我将解答一下经常有人问的问题:

    1.如果我们用HealthKit写入数据,那么我在其他App中读取数据,那么这个数据是不是很大(比如微信的步数排行榜)?

            首先我们介绍一下微信运动,当我们首次打开微信运动的时候会出现一个提示框,询问是否允许访问健康App,由此可以证明微信运动就是通过HealthKit来访问数据的。那么会不会出现我们上面提到的问题呢?理论上是会的,前提是微信没有进行数据源判断。上边我们提到了,每条数据我们都可以知道它的来源,通过来源我们就可以过滤数据,微信运动有可能也是通过这种方式来处理了数据(个人猜测),通过此方式来保证数据的准确。

    2.如果我通过HealthKit写入数据后,其他APP通过CMPedometer来访问数据会不会很大?

            首先CMPedometer访问的是核心运动框架的数据,而HealthKit写入的数据只会保存在健康App中,健康App会整合数据,将所有来源的数据进行合并,但是核心运动框架中的数据还是与它分离的,只是HealthKit中也会包含核心运动框架中的数据而已。所以结论就是CMPedometer访问的还是核心运动框架的数据,并不会读取写入的数据。

    相关文章

      网友评论

        本文标题:iOS中计步器的实现方案及原理

        本文链接:https://www.haomeiwen.com/subject/dhatvqtx.html