在iphone设备中我们应该如何的去获取用户所走的步数,其实大概可以有三种方式
1、利用HealthKit框架从健康App中去获取步数,缺点
2、可以利用废弃的CMStepCounter
3、利用 CMPedometer类来获取步数
第一个我就不介绍了,网上有很多教程
简单的介绍下后两个吧。
CMStepCounter在ios8出来的时候被废弃,原因其实就是因为它其实获取数据不是那么的准确,以及它的功能太有限了,举个例子下面只能判断步数是否可以获取。
//判断硬件是否可用 if(![CMStepCounter isStepCountingAvailable]) { return; } CMStepCounter * stepCounter = [[CMStepCounter alloc]init]; [stepCounter startStepCountingUpdatesToQueue:[NSOperationQueue new] updateOn:1 withHandler:^(NSInteger numberOfSteps, NSDate * _Nonnull timestamp, NSError * _Nullable error) { dispatch_sync(dispatch_get_main_queue(), ^{ self.StepLabel.text = [NSString stringWithFormat:@"你走了多少步:%ld",(long)numberOfSteps]; }); }];
效果图如下所示
所以在ios8的时候新出了一个类CMPedometer,这个类就可以判断很多东西也可以获取很多东西了,当然这个也是有延迟性的
用法如下这里需要注意的就是我们获取数据都是在CMPedometerData这个类中通过它的属性来获取,属性有很多就不一一列举了。简单的列出几个
@property(readonly, nonatomic) NSDate *startDate;//开始时间
@property(readonly, nonatomic) NSDate *endDate;//结束时间
@property(readonly, nonatomic) NSNumber *numberOfSteps;//步数
@property(readonly, nonatomic, nullable) NSNumber *distance;//距离
@property(readonly, nonatomic, nullable) NSNumber *floorsAscended;//上了几个楼
@property(readonly, nonatomic, nullable) NSNumber *floorsDescended;//下了多少楼
还有需要注意的是我们这里需要去在info.plist文件中去设置下面这个选项否则就会崩溃
还有需要注意的是CMPedometer对象要声明为属性,否则会报下面这样的错误
//1、也要先去判断硬件是否可用 if(![CMPedometer isStepCountingAvailable]) { NSLog(@"设备不可用"); return; } self.pedometer=[CMPedometer new]; [self.pedometer startPedometerUpdatesFromDate:[NSDate date] withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) { if(error) { NSLog(@"%@",error); return; } NSNumber * number = pedometerData.numberOfSteps; NSLog(@"%@",[NSThread currentThread]); [self performSelectorOnMainThread:@selector(changeStep:) withObject:number waitUntilDone:YES]; NSLog(@"1"); }]; } -(void)changeStep:(NSNumber *)number { [NSThread sleepForTimeInterval:5]; self.StepLabel.text = [NSString stringWithFormat:@"你走了多少步:%d", number.intValue]; NSLog(@"2"); }
得到的效果如下所示
这里需要注意的是startPedometerUpdatesFromDate的回调方法是在子线程中调用的
我们要更新UI的话肯定要在主线程中进行更新,还有这里需要注意的是performSelectorOnMainThread:@selector(changeStep:) withObject:number waitUntilDone:YES]
这个方法的第三个参数waitUntilDone为YES的话表示阻塞当前线程直到指定选择器在主线程中执行完毕。选择YES会阻塞这个线程;选择NO,本方法会立刻返回。
如果为YES的话调用的结果如下所示
如果为NO的话
还有就是在主线程中也是一样的,当这个参数为YES,时表示当前runloop循环中的时间马上响应这个事件,如果为NO则runloop会将这个事件加入runloop队列在合适的时间执行这个事件。所以如果为YES,就会把我们上面的想让它先执行的方法先执行了。
当然我们也可以选择获取自己今天走的步数,是和苹果健康软件中的是一样的,下面是设置时间,然后我们在startPedometerUpdatesFromDate:传入lastDate就可以了
NSTimeInterval timeInterval =12*60*60; NSDate *date =[NSDate date]; NSDate *lastDate =[date dateByAddingTimeInterval:-timeInterval];
停止更新步数
[self.pedometer stopPedometerUpdates];
分享图片
分享图片