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

前言

当前社会随着社会水平的越来越高,人民饮食也更加的丰富多样,随之而来就成就了越来越多可爱的胖子。胖子多了,一些“不良商贩”发现商机研发出了运动健身类的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访问的还是核心运动框架的数据,并不会读取写入的数据。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342