iOS 教你修改運(yùn)動(dòng)步數(shù)(基于Healthkit)

近日,看到糯米粉寫(xiě)的文章iOS 教你如何修改微信運(yùn)動(dòng)步數(shù) ,趁著五一放假,也想來(lái)玩一下改微信運(yùn)動(dòng)步數(shù),占領(lǐng)一下朋友圈封面,裝裝逼,奈何看到作者用的都是基于逆向工程的一些比較深入的知識(shí),而且要滿足iphone手機(jī)越獄的條件,像我這種小菜鳥(niǎo),自己手里的iphone總是第一時(shí)間更新系統(tǒng)暫時(shí)沒(méi)辦法越獄.俗話說(shuō)條條大路通羅馬,自己就倒騰了下下蘋(píng)果的healthkit,能不能改微信步數(shù)結(jié)尾再說(shuō)????

思路

糯米粉基于逆向工程的應(yīng)用的方案中,是直接在微信頭文件中發(fā)現(xiàn),WCDeviceStepObject這個(gè)類里面有很顯眼的屬性m7StepCount,hkStepCount,一猜就是用來(lái)記錄運(yùn)動(dòng)步數(shù)的屬性, 然后直接編寫(xiě)Tweak.xm,修改m7StepCount的get方法,直接返回一個(gè)運(yùn)動(dòng)步數(shù),就可以修改自己微信的運(yùn)動(dòng)步數(shù)了.當(dāng)然,糯米粉寫(xiě)這篇文章的本意只是通過(guò)一個(gè)熱點(diǎn),把大家?guī)肽嫦蚬こ踢@個(gè)領(lǐng)域.而我寫(xiě)這篇文章,雖然也是用的同樣的概念,但是和糯米粉的側(cè)重點(diǎn)不一樣,因?yàn)槲沂稚蠜](méi)有越獄的手機(jī),對(duì)逆向工程了解也不夠深,所以我這篇文章主要是學(xué)習(xí)蘋(píng)果的healthKit框架,打通各種第三方app和蘋(píng)果本身健康應(yīng)用之間的數(shù)據(jù)通道,實(shí)現(xiàn)各種健康數(shù)據(jù)(包括但不限于運(yùn)動(dòng)步數(shù))在第三方應(yīng)用和蘋(píng)果健康應(yīng)用之間的讀寫(xiě).

條件

  • 非越獄蘋(píng)果手機(jī)(當(dāng)然,越獄的也行),iOS 8 以上,因?yàn)閕OS8以上才有蘋(píng)果健康應(yīng)用.
  • 蘋(píng)果證書(shū),創(chuàng)建app id的時(shí)候必須Enable HealthKit,告訴蘋(píng)果,你要使用healthKit.


    healthkit.png

HealthKit

  • 什么是HealthKit
    簡(jiǎn)單的說(shuō),HealthKit就是iOS8 以后出現(xiàn)的,蘋(píng)果用來(lái)生成,存儲(chǔ),查詢各種健康數(shù)據(jù)的一個(gè)API,包括iPhone本身創(chuàng)建的健身數(shù)據(jù),或者第三方app創(chuàng)建的健康數(shù)據(jù),都可以通過(guò)這個(gè)API進(jìn)行讀取和查詢.也可以把HealthKit看成iPhone的健康數(shù)據(jù)的一個(gè)統(tǒng)一的數(shù)據(jù)庫(kù),同一個(gè)手機(jī)上的不用app的健康數(shù)據(jù)的讀取都是直接面向healthKit,由HealthKit統(tǒng)一管理,來(lái)實(shí)現(xiàn)iOS上不同應(yīng)用之間的健康數(shù)據(jù)的交互.所以說(shuō),微信(包括qq或者其他第三方app)上的運(yùn)動(dòng)步數(shù),本質(zhì)上也是通過(guò)HealthKit來(lái)讀取的,所以,我們只需要新建一個(gè)app(當(dāng)然,我這里只做開(kāi)發(fā)環(huán)境),請(qǐng)求對(duì)HealthKit數(shù)據(jù)的寫(xiě)入權(quán)限,添加運(yùn)動(dòng)步數(shù)后,微信(包括qq或者其他第三方app)通過(guò)HealthKit讀取我們手機(jī)上的健康數(shù)據(jù)中的運(yùn)動(dòng)步數(shù)后,自然讀取后的運(yùn)動(dòng)步數(shù)就可以由我們隨心所欲來(lái)修改了.當(dāng)然,healthKit里面包含各種各種的健康數(shù)據(jù),包括步數(shù),睡眠,運(yùn)動(dòng)距離,卡路里,血壓等等.想要查看這些數(shù)據(jù)非常簡(jiǎn)單,打開(kāi)iPhone里面蘋(píng)果自帶的健康應(yīng)用,非常直觀的展示了我們的健康數(shù)據(jù).


    iPhone健康應(yīng)用
  • HealthKit框架

  1. HKUnit: 由于健康數(shù)據(jù)包括各種各樣數(shù)據(jù)類型,HealthKit對(duì)這些數(shù)據(jù)進(jìn)行了統(tǒng)一規(guī)范,HKUnit包括了Mass,Length,Volume,Pressure,Time,Energy,Temperature,Electrical Conductance,Scalar等各種數(shù)據(jù)類型.
    <pre>
    [HKUnit countUnit]
    </pre>

2.HKQuantity:通過(guò)數(shù)據(jù)類型HKUnit,把我們數(shù)學(xué)意義上的數(shù)量轉(zhuǎn)換成HealthKit的數(shù)據(jù).
<pre>
HKQuantity *stepQuantityConsumed = [HKQuantity quantityWithUnit:[HKUnit countUnit] doubleValue:stepNum];quantityWithUnit:poundUnit doubleValue:weight];
</pre>

3.HKObjectType:健康數(shù)據(jù)的類型,包括運(yùn)動(dòng)步數(shù),心率,卡路里等等(參考下圖).


常見(jiàn)HKQuantityType

另外,按照類型, HKQuantityType又可以細(xì)分為以下幾種:

  • HKCharacteristicType:一般用來(lái)表示那些通常并不會(huì)隨著時(shí)間而變化的健康數(shù)據(jù)類型,蘋(píng)果提供了三種:biological sex, blood type and birthdate,這類數(shù)據(jù)第三方app不能去創(chuàng)建,只能從HealthKit store中讀取.

  • HKCategoryType:用來(lái)表示類別,在iOS中,只有一種,sleep analysis,表示睡眠的質(zhì)量類別.

  • HKQuantityType:除了上面兩種類型的其他健康數(shù)據(jù)類型.


    HKQuantityType
  • HKObjectType一般都根據(jù)identifier來(lái)創(chuàng)建的
    <pre>
    +(nullable HKQuantityType *)quantityTypeForIdentifier:(NSString *)identifier;
    +(nullable HKCategoryType *)categoryTypeForIdentifier:(NSString *)identifier;
    +(nullable HKCharacteristicType *)characteristicTypeForIdentifier:(NSString *)identifier;
    </pre>

4.HKObject:有數(shù)據(jù)類型,自然有對(duì)應(yīng)數(shù)據(jù)對(duì)象

HKObject
  • 下面代碼是一個(gè)如何創(chuàng)建運(yùn)動(dòng)步數(shù)的HKObject的例子
    <pre>
    NSDate *endDate = [NSDate date];
    NSDate *startDate = [NSDate dateWithTimeInterval:-300 sinceDate:endDate];

    HKQuantity *stepQuantityConsumed = [HKQuantity quantityWithUnit:[HKUnit countUnit] doubleValue:stepNum];

    HKQuantityType *stepConsumedType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
    </pre>

5.HKHealthStore:healthKit的管理器,用來(lái)鏈接到數(shù)據(jù)庫(kù),保存和查詢數(shù)據(jù),在app中必須一直被持有(should be long lived).類似下面的操作均是HKHealthStore的對(duì)象方法.
<pre>
-(void)saveObject:(HKObject *)object withCompletion:(void(^)(BOOL success, NSError * __nullable error))completion;
-(void)executeQuery:(HKQuery *)query;
-(void)deleteObject:(HKObject *)object withCompletion:(void(^)(BOOL success, NSError * __nullable error))completion;
</pre>

6.HKQuery:healthKit數(shù)據(jù)的查詢
<pre>
/*!
@method initWithSampleType:predicate:limit:sortDescriptors:resultsHandler:
@abstract Returns a query that will retrieve HKSamples matching the given predicate.

@param sampleType The type of sample to retrieve.
@param predicate The predicate which samples should match.
@param limit The maximum number of samples to return. Pass HKObjectQueryNoLimit for no limit.
@param sortDescriptors The sort descriptors to use to order the resulting samples.
@param resultsHandler The block to invoke with results when the query has finished executing.
*/
-(instancetype)initWithSampleType:(HKSampleType *)sampleType
predicate:(nullable NSPredicate *)predicate
limit:(NSUInteger)limit
sortDescriptors:(nullable NSArray<NSSortDescriptor *> *)sortDescriptors
resultsHandler:(void(^)(HKSampleQuery *query, NSArray<__kindof HKSample *> * __nullable results, NSError * __nullable error))resultsHandler;
</pre>

HKQuery的方法可以見(jiàn)上面,包括各種查詢數(shù)據(jù)的類型,條件,篩選,排序,次數(shù)等等,這里就不詳細(xì)說(shuō)了,有需要的可以自己多了解,簡(jiǎn)單寫(xiě)一個(gè)查詢運(yùn)動(dòng)數(shù)量的示例:
<pre>
[self fetchSumOfSamplesTodayForType:stepType unit:[HKUnit countUnit] completion:^(double stepCount, NSError *error) {
NSLog(@"%f",stepCount);
dispatch_async(dispatch_get_main_queue(), ^{
_readStepLabel.text = [NSString stringWithFormat:@"%.f",stepCount];
});
}];

  • (void)fetchSumOfSamplesTodayForType:(HKQuantityType *)quantityType unit:(HKUnit *)unit completion:(void (^)(double, NSError *))completionHandler {
    NSPredicate *predicate = [self predicateForSamplesToday];

    HKStatisticsQuery *query = [[HKStatisticsQuery alloc] initWithQuantityType:quantityType quantitySamplePredicate:predicate options:HKStatisticsOptionCumulativeSum completionHandler:^(HKStatisticsQuery *query, HKStatistics *result, NSError *error) {
    HKQuantity *sum = [result sumQuantity];

      if (completionHandler) {
          double value = [sum doubleValueForUnit:unit];
          
          completionHandler(value, error);
      }
    

    }];

    [self.healthStore executeQuery:query];
    }
    </pre>

動(dòng)手改運(yùn)動(dòng)步數(shù)

前面簡(jiǎn)單介紹了healthKit的整個(gè)框架,要修改微信或者其他第三方app的健康數(shù)據(jù),只需要修改蘋(píng)果中HKHealthStore的數(shù)據(jù)即可,應(yīng)該第三方app均是讀取HKHealthStore的數(shù)據(jù)的.說(shuō)一下簡(jiǎn)單步驟:
首先獲取讀取權(quán)限,獲得讀取權(quán)限后,將運(yùn)動(dòng)步數(shù)的數(shù)據(jù)寫(xiě)入HKHealthStore.第三方應(yīng)用就會(huì)自動(dòng)去利用HKHealthStore去更新數(shù)據(jù)了,就是這么簡(jiǎn)單.

  • 打包到真機(jī),授權(quán)權(quán)限后添加步數(shù)


    IMG_3796.PNG
  • 添加成功


    IMG_3794.PNG
  • 實(shí)時(shí)同步到qq的健康排行榜

B9995FE24C397449EFB07F50D3AEE479.png
  • qq的健康每走滿1萬(wàn)步,可以捐1萬(wàn)步抵一塊錢做公益,最多可以一天捐3快,這是我做這個(gè)小玩意最大的收獲,如果你有幸看到了,也想為公益做點(diǎn)事,沒(méi)事就多在qq這里捐步數(shù)做做公益吧??


    IMG_3798.PNG
  • 然而,我發(fā)現(xiàn)微信并不是直接讀取HKHealthStore中步數(shù)的總數(shù)這么簡(jiǎn)單,我自己添加的步數(shù)微信并不會(huì)同步,我研究了下,iOS9 中,添加數(shù)據(jù)的時(shí)候,iOS會(huì)自動(dòng)幫我們添加數(shù)據(jù)來(lái)源,我們自己也可以添加設(shè)備信息.如下圖:
    我覺(jué)得應(yīng)該是最近刷微信運(yùn)動(dòng)步數(shù)的情況比較嚴(yán)重,微信采取了一些措施,最大的可能是微信并不是直接讀取運(yùn)動(dòng)步數(shù)總數(shù),而且會(huì)先判定數(shù)據(jù)來(lái)源,不是微信認(rèn)可的設(shè)備以及iPhone自身運(yùn)動(dòng)處理器記錄的步數(shù),微信不會(huì)同步,所以,這種我們自己的app隨便寫(xiě)的數(shù)據(jù),去改微信步數(shù)以失敗告終,看來(lái)想改微信的話,還是需要往逆向工程方向去操作.

IMG_3795.PNG

結(jié)語(yǔ)

雖然并沒(méi)有成功實(shí)現(xiàn)更改微信的運(yùn)動(dòng)步數(shù),但是,我覺(jué)得,結(jié)果并不重要,重要的是我們學(xué)習(xí)了HealthKit,有所收獲,懂得原理.

最后,雖然這個(gè)很簡(jiǎn)單,我還是把Demo地址放一下吧,Demo實(shí)在蘋(píng)果Healthkit原先的Demo基礎(chǔ)上添加修改步數(shù)的功能.HealthKitDemo

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

相關(guān)閱讀更多精彩內(nèi)容

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