iOS中計(jì)步器的實(shí)現(xiàn)方案及原理

前言

當(dāng)前社會隨著社會水平的越來越高艰亮,人民飲食也更加的豐富多樣,隨之而來就成就了越來越多可愛的胖子娃圆。胖子多了蔫慧,一些“不良商販”發(fā)現(xiàn)商機(jī)研發(fā)出了運(yùn)動健身類的APP挠乳,如:Keep,咕咚,動動睡扬,趣走等等盟蚣,就連我們的移動社交老大哥騰訊也相繼推出了微信運(yùn)動,qq運(yùn)動等功能卖怜。那么今天我將通過此篇文章來給大家簡單介紹一下在我們的iOS中想要實(shí)現(xiàn)一個計(jì)步器的功能有哪幾種方案刁俭,以及實(shí)現(xiàn)它的一些原理。


實(shí)現(xiàn)方案

從目前技術(shù)角度來看韧涨,ios實(shí)現(xiàn)計(jì)步功能主要有三種方案:加速計(jì)牍戚,CMPedometer,HealthKit。下面我們分別來說說這三種實(shí)現(xiàn)方案虑粥。


一如孝、加速計(jì)

iOS4以后蘋果已經(jīng)提供了CoreMotion(核心運(yùn)動框架),但是并沒有提供給我們關(guān)于步數(shù)計(jì)算和行走公里數(shù)的計(jì)算方法娩贷。iOS7出現(xiàn)以后蘋果在CoreMotion中添加了CMStepCounter第晰,此時(shí)我們就可以通過CMStepCounter來計(jì)算行走的步數(shù)和公里數(shù)據(jù)了。iOS8的時(shí)候又出現(xiàn)了CMPedometer彬祖,它是CMStepCounter的替代者茁瘦,CMPedometer中的數(shù)據(jù)種類也變得更加多樣,比如我們不只可以獲取步數(shù)和公里數(shù)储笑,我們還可以計(jì)算我們的上下樓層數(shù)甜熔,以及我們活動的平均速度等等。但是由于硬件的緣故突倍,在iPhone5s以下的設(shè)備中沒有協(xié)處理器腔稀,就設(shè)備本身來講我們是無法通過手機(jī)去計(jì)算步數(shù)和公里數(shù)的。難道這樣我們就放棄了我們要做計(jì)步器的初衷了嗎羽历?當(dāng)然不是焊虏,下面我們就來介紹在iPhone5s以下設(shè)備中比較流行的一種計(jì)步器的實(shí)現(xiàn)方案——加速計(jì)

加速計(jì)是CoreMotion框架中用來計(jì)算設(shè)備在三維空間中的加速度的。那么我們?nèi)绾瓮ㄟ^加速計(jì)來計(jì)算步數(shù)呢秕磷?接下來我將詳細(xì)介紹加速計(jì)計(jì)算步數(shù)的原理诵闭。


原理

我們通過加速計(jì)來進(jìn)行特性分析,分別用以檢測人步行中三個方向的加速度變化澎嚣,如下圖


當(dāng)我們在水平步行運(yùn)動中疏尿,垂直和前進(jìn)兩個加速度會呈現(xiàn)周期性變化,如圖下圖所示币叹,在步行收腳的動作中润歉,由于重心向上單只腳觸地模狭,垂直方向加速度是呈正向增加的趨勢颈抚,之后繼續(xù)向前,重心下移兩腳觸底,加速度相反贩汉。水平加速度在收腳時(shí)減小驱富,在邁步時(shí)增加。

反映到圖表中匹舞,我們可以看到在步行運(yùn)動中褐鸥,垂直和前進(jìn)產(chǎn)生的加速度與時(shí)間大致為一個正弦曲線,而且在某點(diǎn)有一個峰值赐稽,其中垂直方向的加速度變化最大叫榕,通過對軌跡的峰值進(jìn)行檢測計(jì)算和加速度閾值決策,即可實(shí)時(shí)計(jì)算用戶運(yùn)動的步數(shù)姊舵。

?因?yàn)橛脩粼谶\(yùn)動中可能手平持設(shè)備或者將設(shè)備置于口袋中晰绎,所以設(shè)備的放置方向不定,為此我們通過計(jì)算三個加速度的矢量長度括丁,獲得一條步行運(yùn)動的正弦曲線軌跡荞下。

  第二步是峰值檢測,我們記錄了上次矢量長度和運(yùn)動方向史飞,通過矢量長度的變化尖昏,可以判斷目前加速度的方向,并和上一次保存的加速度方向進(jìn)行比較构资,如果是相反的抽诉,即是剛過峰值狀態(tài),則進(jìn)入計(jì)步邏輯進(jìn)行計(jì)步吐绵,否則舍棄掸鹅。通過對峰值的次數(shù)累加可得到用戶步行步伐。

  最后是去多余的干擾拦赠,手持設(shè)備會有一些低幅度和快速的移動狀態(tài)巍沙,或是我們說的手抖和快速甩動,或者某個惡作劇用戶想通過短時(shí)快速反復(fù)搖動設(shè)備來模擬人走路(當(dāng)然也包括哪些將手機(jī)捆綁在狗尾巴上的天才)荷鼠,這些干擾數(shù)據(jù)如果不剔除句携,會影響記步的準(zhǔn)確值,對于這種干擾允乐,我們可以通過給檢測加上閾值和步頻判斷來過濾矮嫉。比如我們可以設(shè)置一個一步所用的時(shí)間,如果短于這個時(shí)間我們就過濾掉牍疏。就像博爾特蠢笋,100米最快也需要9.69s。如果有生物跑100米所用時(shí)間小于8秒了鳞陨,按照現(xiàn)在的身體極限我們就可以斷定這個生物99.9%不是人類昨寞。


二、CMPedometer

iOS8以后,CoreMotion框架中為我們提供了一個獲取用戶活動信息的對象CMPedometer,通過CMPedometer我們可以獲取用戶的活動信息援岩,如:行走步數(shù)歼狼,行走的公里數(shù),上下樓層數(shù)以及平均速度等享怀。因此我們通過CMPedometer調(diào)用它的API接口就完全可以獲取到我們想要的步數(shù)羽峰。下邊我將介紹一下我們用到的API。

1.?當(dāng)我們在使用CMPedometer查詢我們需要的數(shù)據(jù)的時(shí)候添瓷,比如:步數(shù)梅屉,公里數(shù),上下樓層數(shù)等鳞贷,我們需要先通過判斷接口判斷設(shè)備中的這些功能是否可用履植,如下邊方法:

//判斷計(jì)步器是否可用

+ (BOOL)isStepCountingAvailable;

//是否支持距離估計(jì)

+ (BOOL)isDistanceAvailable;

//是否支持樓梯計(jì)數(shù)

+?(BOOL)isFloorCountingAvailable;

//等等,不一一進(jìn)行介紹了悄晃。

?2.?因?yàn)槲覀冃枰獜脑O(shè)備中獲取我們需要的活動數(shù)據(jù)玫霎,所以我們需要調(diào)用的是設(shè)備的數(shù)據(jù)查詢接口,如下邊方法:

//此方法是從某一時(shí)間段開始妈橄,連續(xù)的采集數(shù)據(jù)庶近,當(dāng)設(shè)備中的活動數(shù)據(jù)發(fā)生變更就會回調(diào)此方法,此方法是在串行隊(duì)列中執(zhí)行眷蚓。

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

//此方法是查詢某一時(shí)間段的數(shù)據(jù)鼻种,時(shí)間可長達(dá)7天,此方法是在串行隊(duì)列中執(zhí)行沙热。

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

3.?廢話不多說叉钥,直接上代碼?

連續(xù)獲取數(shù)據(jù)

?獲取某一時(shí)間段的數(shù)據(jù)

更新UI


三、HealthKit

?? ????iOS8以后蘋果推出了一個新的手機(jī)自帶的App——健康A(chǔ)pp篙贸,這個App就是用來顯示我們的活動信息的投队。并且蘋果還為我們提供了一個訪問健康A(chǔ)pp的框架HealthKit。我們可以理解HealthKit是一個活動數(shù)據(jù)的中央存儲庫爵川,而健康A(chǔ)pp是用來展示這個庫中的數(shù)據(jù)的敷鸦。那么HealthKit是如何獲取用戶的活動數(shù)據(jù)的呢?首先我們想一下寝贡,健康A(chǔ)pp中的運(yùn)動數(shù)據(jù)是從哪兒來的扒披?運(yùn)動信息嘛當(dāng)然是從核心運(yùn)動框架里邊來的了,那么訪問核心運(yùn)動框架中的信息都是通過CMPedometer來訪問的圃泡,所以我們就知道了HealthKit底層也是通過上邊我們提到CMPedometer來獲取用戶信息的碟案,只不過它的獲取方法在手機(jī)內(nèi)部,通過協(xié)處理器來進(jìn)行計(jì)算的颇蜡。而協(xié)處理器在5s以后的設(shè)備中才出現(xiàn)的价说,所以在5s以前的設(shè)備中是無法獲取用戶的運(yùn)動信息的辆亏。

??

我們在使用HealthKit的時(shí)候的注意事項(xiàng):

A:需要把HealthKit配置到AppID中

B:Xocede中需要打開HealthKit的開關(guān)選項(xiàng)

C:需要調(diào)用isHealthDataAvailable方法檢測HealthKit是否可用

D:在讀取和寫入數(shù)據(jù)之前需要先獲取權(quán)限,并且設(shè)置讀取和寫入的數(shù)據(jù)類型


申請權(quán)限

F:在info.plist文件中熔任,增加NSHealthShareUsageDescription用于讀取數(shù)據(jù)的描述和NSHealthUpdateUsageDescription用于寫入數(shù)據(jù)的描述。


設(shè)置好上面的配置信息后我們?nèi)绾卧L問和讀取數(shù)據(jù)呢唁情,下邊我們將以特征數(shù)據(jù)(性別)和樣本數(shù)據(jù)(步數(shù))為例疑苔,話不多說,直接上代碼甸鸟。


性別讀鹊敕选:

特征數(shù)據(jù)我們一般都是用HKHealthStore直接訪問,返回一個性別類型對象抢韭,然后通過對象值判斷性別薪贫。


?注意:特征數(shù)據(jù)只能讀取不能寫入,如何修改的話只能通過健康A(chǔ)pp來修改


步數(shù)讀瓤坦А:

a:事例查詢

此查詢方式為事例查詢瞧省,可以查詢到每一條寫入的數(shù)據(jù),并且能可以獲取數(shù)據(jù)的來源鳍贾,通過來源可以分析數(shù)據(jù)是設(shè)備背身記錄的數(shù)據(jù)還是三方app寫入的數(shù)據(jù)鞍匾。


b:統(tǒng)計(jì)查詢

此查詢方式為統(tǒng)計(jì)查詢,查詢結(jié)果為步數(shù)的總和骑科,不區(qū)分?jǐn)?shù)據(jù)來源橡淑。



步數(shù)寫入:

寫入數(shù)據(jù)一般我們采用saveObject的形式


以上為三種實(shí)現(xiàn)計(jì)步器的實(shí)現(xiàn)方案,下邊我將解答一下經(jīng)常有人問的問題:

1.如果我們用HealthKit寫入數(shù)據(jù)咆爽,那么我在其他App中讀取數(shù)據(jù)梁棠,那么這個數(shù)據(jù)是不是很大(比如微信的步數(shù)排行榜)?

????????首先我們介紹一下微信運(yùn)動斗埂,當(dāng)我們首次打開微信運(yùn)動的時(shí)候會出現(xiàn)一個提示框符糊,詢問是否允許訪問健康A(chǔ)pp,由此可以證明微信運(yùn)動就是通過HealthKit來訪問數(shù)據(jù)的呛凶。那么會不會出現(xiàn)我們上面提到的問題呢濒蒋?理論上是會的,前提是微信沒有進(jìn)行數(shù)據(jù)源判斷把兔。上邊我們提到了沪伙,每條數(shù)據(jù)我們都可以知道它的來源,通過來源我們就可以過濾數(shù)據(jù)县好,微信運(yùn)動有可能也是通過這種方式來處理了數(shù)據(jù)(個人猜測)围橡,通過此方式來保證數(shù)據(jù)的準(zhǔn)確。


2.如果我通過HealthKit寫入數(shù)據(jù)后缕贡,其他APP通過CMPedometer來訪問數(shù)據(jù)會不會很大翁授?

????????首先CMPedometer訪問的是核心運(yùn)動框架的數(shù)據(jù)拣播,而HealthKit寫入的數(shù)據(jù)只會保存在健康A(chǔ)pp中,健康A(chǔ)pp會整合數(shù)據(jù)收擦,將所有來源的數(shù)據(jù)進(jìn)行合并贮配,但是核心運(yùn)動框架中的數(shù)據(jù)還是與它分離的,只是HealthKit中也會包含核心運(yùn)動框架中的數(shù)據(jù)而已塞赂。所以結(jié)論就是CMPedometer訪問的還是核心運(yùn)動框架的數(shù)據(jù)泪勒,并不會讀取寫入的數(shù)據(jù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宴猾,一起剝皮案震驚了整個濱河市圆存,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌仇哆,老刑警劉巖沦辙,帶你破解...
    沈念sama閱讀 216,843評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異讹剔,居然都是意外死亡油讯,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評論 3 392
  • 文/潘曉璐 我一進(jìn)店門延欠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來撞羽,“玉大人,你說我怎么就攤上這事衫冻【魑桑” “怎么了?”我有些...
    開封第一講書人閱讀 163,187評論 0 353
  • 文/不壞的土叔 我叫張陵隅俘,是天一觀的道長邻奠。 經(jīng)常有香客問我,道長为居,這世上最難降的妖魔是什么碌宴? 我笑而不...
    開封第一講書人閱讀 58,264評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮蒙畴,結(jié)果婚禮上贰镣,老公的妹妹穿的比我還像新娘。我一直安慰自己膳凝,他們只是感情好碑隆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,289評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蹬音,像睡著了一般上煤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上著淆,一...
    開封第一講書人閱讀 51,231評論 1 299
  • 那天劫狠,我揣著相機(jī)與錄音拴疤,去河邊找鬼。 笑死独泞,一個胖子當(dāng)著我的面吹牛呐矾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播懦砂,決...
    沈念sama閱讀 40,116評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蜒犯,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了孕惜?” 一聲冷哼從身側(cè)響起愧薛,我...
    開封第一講書人閱讀 38,945評論 0 275
  • 序言:老撾萬榮一對情侶失蹤晨炕,失蹤者是張志新(化名)和其女友劉穎衫画,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瓮栗,經(jīng)...
    沈念sama閱讀 45,367評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡削罩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,581評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了费奸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弥激。...
    茶點(diǎn)故事閱讀 39,754評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖愿阐,靈堂內(nèi)的尸體忽然破棺而出微服,到底是詐尸還是另有隱情,我是刑警寧澤缨历,帶...
    沈念sama閱讀 35,458評論 5 344
  • 正文 年R本政府宣布以蕴,位于F島的核電站,受9級特大地震影響辛孵,放射性物質(zhì)發(fā)生泄漏丛肮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,068評論 3 327
  • 文/蒙蒙 一魄缚、第九天 我趴在偏房一處隱蔽的房頂上張望宝与。 院中可真熱鬧,春花似錦冶匹、人聲如沸习劫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽榜聂。三九已至,卻和暖如春嗓蘑,著一層夾襖步出監(jiān)牢的瞬間须肆,已是汗流浹背匿乃。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留豌汇,地道東北人幢炸。 一個月前我還...
    沈念sama閱讀 47,797評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像拒贱,于是被迫代替她去往敵國和親宛徊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,654評論 2 354