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

前言

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


實現(xiàn)方案

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


一、加速計

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

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


原理

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


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

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

?因為用戶在運動中可能手平持設(shè)備或者將設(shè)備置于口袋中,所以設(shè)備的放置方向不定,為此我們通過計算三個加速度的矢量長度,獲得一條步行運動的正弦曲線軌跡。

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

  最后是去多余的干擾,手持設(shè)備會有一些低幅度和快速的移動狀態(tài),或是我們說的手抖和快速甩動,或者某個惡作劇用戶想通過短時快速反復(fù)搖動設(shè)備來模擬人走路(當(dāng)然也包括哪些將手機捆綁在狗尾巴上的天才),這些干擾數(shù)據(jù)如果不剔除,會影響記步的準(zhǔn)確值,對于這種干擾,我們可以通過給檢測加上閾值和步頻判斷來過濾。比如我們可以設(shè)置一個一步所用的時間,如果短于這個時間我們就過濾掉。就像博爾特,100米最快也需要9.69s。如果有生物跑100米所用時間小于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è)備中的這些功能是否可用,如下邊方法:

//判斷計步器是否可用

+ (BOOL)isStepCountingAvailable;

//是否支持距離估計

+ (BOOL)isDistanceAvailable;

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

+?(BOOL)isFloorCountingAvailable;

//等等,不一一進行介紹了。

?2.?因為我們需要從設(shè)備中獲取我們需要的活動數(shù)據(jù),所以我們需要調(diào)用的是設(shè)備的數(shù)據(jù)查詢接口,如下邊方法:

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

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

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

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

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

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

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

更新UI


三、HealthKit

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

??

我們在使用HealthKit的時候的注意事項:

A:需要把HealthKit配置到AppID中

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

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ù)讀?。?/b>

a:事例查詢

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


b:統(tǒng)計查詢

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



步數(shù)寫入:

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


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

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

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


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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容