您好,登錄后才能下訂單哦!
這篇文章介紹兩種可以獲取計步數據的方法,一種是采用CMPedometer獲取手機計步器數據,另一種是采用HealthKit框架從手機健康App中獲取計步數據。另外玩了一下寫入數據到健康App。有描述不當之處,望指點。
花絮(用HealthKit框架構建app,寫入數據到蘋果健康app中,QQ和Keep等第三方app的運動數據都會隨之改變,猜測它們的運動數據是直接從蘋果健康app中獲取,而且沒有過濾掉其它數據來源。而微信運動的數據不會變,猜測其來源可能是使用CMPedometer類獲取的,因為測試發現把微信運動的數據來源(蘋果健康)關閉后,依然會有運動數據,而且該運動數據和CMPedometer類獲取的一致。)
使用CMPedometer類來獲取步數和距離
使用時需要導入<CoreMotion/CoreMotion.h>,此類在iOS8之后才可用,在iOS8之前,使用CMStepCounter類(在iOS8之后被CMPedometer替代)來獲取步數,使用方法如CMPedometer類相似。
CMPedometer
+ (BOOL)isStepCountingAvailable; 設備是否支持計步功能
+ (BOOL)isDistanceAvailable; 除了計步,設備是否支持距離估計
+ (BOOL)isFloorCountingAvailable; 除了計步,設備是否支持臺階計數
+ (BOOL)isPaceAvailable NS_AVAILABLE(NA,9_0);除了計步,設備是否支持速度估計
+(BOOL)isCadenceAvailable NS_AVAILABLE(NA,9_0);除了計步,設備是否支持節奏估計
+ (BOOL)isPedometerEventTrackingAvailable NS_AVAILABLE(NA,10_0) __WATCHOS_AVAILABLE(3_0);設備是否支持計步器事件
- (void)queryPedometerDataFromDate:(NSDate *)start toDate:(NSDate *)end withHandler:(CMPedometerHandler)handler;在給定時間范圍內查詢用戶的行走活動,數據最多可以使用7天內有效,返回的數據是從系統范圍的歷史記錄中計算出來的,該歷史記錄是在后臺連續收集的。結果返回在串行隊列中。
- (void)startPedometerUpdatesFromDate:(NSDate *)start withHandler:(CMPedometerHandler)handler;在串行隊列上啟動一系列連續計步器更新到處理程序。 對于每次更新,應用程序將從指定的開始日期和與最新確定相關聯的時間戳開始收到累積的行人活動。 如果應用程序在后臺進行背景調整,則應用程序將在下次更新中收到在后臺期間累積的所有行人活動。
-(void)stopPedometerUpdates;停止計步器更新
-(void)startPedometerEventUpdatesWithHandler:(CMPedometerEventHandler)handler NS_AVAILABLE(NA,10_0) __WATCHOS_AVAILABLE(3_0);在串行隊列上啟動計步器事件更新。 事件僅在應用程序在前臺/后臺運行時可用。
-(void)stopPedometerEventUpdates NS_AVAILABLE(NA,10_0) __WATCHOS_AVAILABLE(3_0);停止計步器事件更新
CMPedometerData
@property(readonly, nonatomic) NSDate *startDate;計步器數據有效期間的開始時間。這是會話或歷史查詢請求的開始時間。
@property(readonly, nonatomic) NSDate *endDate;計步器數據有效期間的結束時間。對于更新,這是最新更新的時間。 對于歷史查詢,這是請求的結束時間。
@property(readonly, nonatomic) NSNumber *numberOfSteps;用戶的步數
@property(readonly, nonatomic, nullable) NSNumber *distance; 用戶行走和跑步時估計的一米為單位的距離。若設備不支持則值為nil
@property(readonly, nonatomic, nullable) NSNumber *floorsAscended;上樓的大概樓層數,若設備不支持則值為nil
@property(readonly, nonatomic, nullable) NSNumber *floorsDescended;下樓的大概樓層數, 若設備不支持則值為nil
@property(readonly, nonatomic, nullable) NSNumber *currentPace NS_AVAILABLE(NA,9_0);對于更新,這將以s / m(每米秒)返回當前速度。 如果滿足以下條件,則值為零:1. 資料尚未公布 2. 歷史查詢 3.平臺不支持
@property(readonly, nonatomic, nullable) NSNumber *currentCadence NS_AVAILABLE(NA,9_0);對于更新,這將返回以秒為單位執行行走的節奏。 如果滿足以下條件,則值為零:1. 資料尚未公布 2. 歷史查詢 3.平臺不支持
@property(readonly, nonatomic, nullable) NSNumber *averageActivePace NS_AVAILABLE(NA,10_0);對于更新,這將返回自startPedometerUpdatesFromDate:withHandler :,以s / m(每米秒))的平均活動速度。 對于歷史查詢,這將返回startDate和endDate之間的平均活動速度。 平均主動速度省略了非活動時間,平均步調從用戶移動。 如果滿足以下條件,則值為零:1. 對于歷史信息查詢,信息無效。例如用戶在開始時間和結束時間內沒有移動 2. 平臺不支持
CMPedometerEvent
@property(readonly, nonatomic) NSDate *date;事件發生的時間
@property(readonly, nonatomic) CMPedometerEventType type;描述行走活動過渡的事件類型
typedef void (^CMPedometerHandler)(CMPedometerData * __nullable pedometerData, NSError * __nullable error) __TVOS_PROHIBITED;當計步器數據可用時要調用的block的類型
typedef void (^CMPedometerEventHandler)(CMPedometerEvent * __nullable pedometerEvent, NSError * __nullable error) NS_AVAILABLE(NA, 10_0) __WATCHOS_AVAILABLE(3_0) __TVOS_PROHIBITED;//當計步器事件可用時將被調用的block的類型。
獲取步數和距離的方法
1、使用<CoreMotion/CoreMotion.h>庫需要在info.plist文件中增加NSMotionUsageDescription鍵。
2、可以使用isStepCountingAvailable或者isDistanceAvailable來檢查設備是否支持計步功能或距離功能。
3、創建CMPedometer實例對象
/// 創建計步器對象 if ([CMPedometer isStepCountingAvailable]) { // 8.0 之后可使用 self.pedometer = [[CMPedometer alloc] init]; }
4、調用- (void)startPedometerUpdatesFromDate:(NSDate *)start withHandler:(CMPedometerHandler)handler方法獲取從某個時間點到現在的步數,距離,樓層等信息。此方法會實時更新數據。
[self.pedometer startPedometerUpdatesFromDate:fromDate withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) { // 如果沒有錯誤,具體信息從pedometerData參數中獲取 }];
5、不需要使用的時候,調用stopPedometerUpdates方法停止更新
[self.pedometer stopPedometerUpdates];
6、如果不需要實時更新數據,可直接調用- (void)queryPedometerDataFromDate:(NSDate *)start toDate:(NSDate *)end withHandler:(CMPedometerHandler)handler;查詢某個時間段內的數據,不過只能查詢七天內的數據。
[self.pedometer queryPedometerDataFromDate:start toDate:end withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) { // 如果沒有錯誤,具體信息從pedometerData參數中獲取 }];
使用HealthKit框架獲取蘋果健康數據
在HealthKit中,使用HKHealthStore類來訪問健康數據,健康數據的類型有很多類,蘋果健康app中的健身記錄、營養攝入、睡眠狀況等等都可以進行數據讀取和共享(即第三方app寫入數據到蘋果健康app)。
大概步驟:
1、在Xcode中, 打開HealthKit 功能
開啟HealthKit功能
1、調用isHealthDataAvailable方法檢查設備HealthKit是否可用。
if ([HKHealthStore isHealthDataAvailable]) { // add code to use HealthKit here... }
2、如果可用,創建HKHealthStore對象
self.healthStore = [[HKHealthStore alloc] init];
3、向用戶請求授權共享或讀取健康數據, 調用- (void)requestAuthorizationToShareTypes:(nullable NSSet<HKSampleType *> *)typesToShare readTypes:(nullable NSSet<HKObjectType *> *)typesToRead completion:(void (^)(BOOL success, NSError * _Nullable error))completion;方法,例如下面請求讀取步數和距離數據
NSSet<HKSampleType *> *shareTypes = nil; HKQuantityType *stepType = [HKQuantityType quantityTypeForIdentifier:(HKQuantityTypeIdentifierStepCount)]; HKQuantityType *distanceType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierDistanceWalkingRunning]; NSSet<HKObjectType *> *readTypes = [NSSet setWithObjects:stepType, distanceType, nil]; [self.healthStore requestAuthorizationToShareTypes:shareTypes readTypes:readTypes completion:^(BOOL success, NSError * _Nullable error) { }];
4、在info.plist文件中,增加NSHealthShareUsageDescription用于讀取數據的描述和NSHealthUpdateUsageDescription用于寫入數據的描述
5、用戶授權之后,就可以對健康數據中授權的項目進行讀取或寫入操作。下面的代碼是查詢一段歷史的計步記錄的示例,如CMPedemoter不同的是查詢到的數據不是實時更新的。
// 查詢數據的類型,比如計步,行走+跑步距離等等 HKQuantityType *quantityType = [HKQuantityType quantityTypeForIdentifier:(HKQuantityTypeIdentifierStepCount)]; // 謂詞,用于限制查詢返回結果 NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:start endDate:end options:(HKQueryOptionNone)]; NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *anchorComponents = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:[NSDate date]]; // 用于錨集合的時間間隔 NSDate *anchorDate = [calendar dateFromComponents:anchorComponents]; // 采樣時間間隔 NSDateComponents *intervalComponents = [[NSDateComponents alloc] init]; intervalComponents.day = 1; // 創建統計查詢對象 HKStatisticsCollectionQuery *query = [[HKStatisticsCollectionQuery alloc] initWithQuantityType:quantityType quantitySamplePredicate:predicate options:(HKStatisticsOptionCumulativeSum|HKStatisticsOptionSeparateBySource) anchorDate:anchorDate intervalComponents:intervalComponents]; query.initialResultsHandler = ^(HKStatisticsCollectionQuery * _Nonnull query, HKStatisticsCollection * _Nullable result, NSError * _Nullable error) { NSMutableArray *resultArr = [NSMutableArray array]; if (error) { NSLog(@"error: %@", error); } else { for (HKStatistics *statistics in [result statistics]) { NSLog(@"statics: %@,\n sources: %@", statistics, statistics.sources); for (HKSource *source in statistics.sources) { // 過濾掉其它應用寫入的健康數據 if ([source.name isEqualToString:[UIDevice currentDevice].name]) { // 獲取到步數 double step = round([[statistics sumQuantityForSource:source] doubleValueForUnit:[HKUnit countUnit]]); } } } } // 執行查詢請求 [self.healthStore executeQuery:query];
如果要寫入數據到蘋果HealtkKit中,過程類似,下面的示例是寫入步數到健康數據。(QQ中運動的步數和Keep中的步數都是從健康數據中獲取的步數,而且沒有過濾其它應用寫入的數據,所以想要修改QQ或Keep中的步數,可以用自己的app寫入步數數據,親測有效)
①請求用戶授權
HKQuantityType *stepType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount]; NSSet *shareTypes = [NSSet setWithObjects:stepType, nil]; [self.healthStore requestAuthorizationToShareTypes:shareTypes readTypes:nil completion:^(BOOL success, NSError * _Nullable error) { }];
②寫入數據
double step = [self.textField.text doubleValue]; HKQuantityType *stepType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount]; HKQuantity *stepQuantity = [HKQuantity quantityWithUnit:[HKUnit countUnit] doubleValue:step]; HKQuantitySample *stepSample = [HKQuantitySample quantitySampleWithType:stepType quantity:stepQuantity startDate:[self getTodayStartDate] endDate:[NSDate date]]; [self.healthStore saveObject:stepSample withCompletion:^(BOOL success, NSError * _Nullable error) { if (error) { NSLog(@"error: %@", error.localizedDescription); } dispatch_async(dispatch_get_main_queue(), ^{ self.stateLabel.text = success ? @"成功" : @"失敗"; }); }];
項目中使用了HealthKit時,上架需要注意點:
You must also provide a privacy policy for any app that uses the HealthKit framework. You can find guidance on creating a privacy policy at the following sites://你必須為每個使用HealthKit框架的應用提供一份隱私策略。你可以在以下網站找到創建隱私策略的指導:
1、Personal Health Record model (for non-HIPAA apps): http://www.healthit.gov/policy-researchers-implementers/personal-health-record-phr-model-privacy-notice
2、HIPAA model (for HIPAA covered apps): http://www.hhs.gov/ocr/privacy/hipaa/modelnotices.html
參考文章
https://developer.apple.com/documentation/healthkit#classes
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。