iOS 获取手机步数

在iphone设备中我们应该如何的去获取用户所走的步数,其实大概可以有三种方式

1、利用HealthKit框架从健康App中去获取步数,缺点

2、可以利用废弃的CMStepCounter

3、利用 CMPedometer类来获取步数

 

大家可能都看过或者知晓HealthKit这个框架,但是实际上,一般去研究过这个框架的,都会知道,实时的获取运动数据,并不是用这个框架的,尤其是步数,这个框架如果你在健康中没有开启步数权限的话,是获取不到的

Healthkit计步有个缺点, 计步不准,有人会问了:这个 Healthkit 和我下面的 demo 不都是用 CMPedometer 来获取计步数的,为什么 Healthkit 不准呢?
答: 那是因为Healthkit记录的时区问题, ios获取时间的时区按中国的时区少了8个小时, 举个例子, 如果我要记录 5月5日的数据应该是 xxxx-05-05 00:00:00 至xxxx-05-05 23:59:59 这个区间的步数情况, 而 Healthkit 记录的时区却是 xxxx-05-04 16:00:00 至 xxxx-05-05 15:59:59 ,所以Healthkit记录的信息是不准的, 如果要是自己开发计步软件呢,我们就要自己写把, 不要获取 Healthkit 的信息啦



作者:贪吃鱼
链接:https://www.jianshu.com/p/e01c5869d95c
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

所以讲到了实时获取运动数据,苹果还提供了另一个框架给我们使用 —— CoreMotion框架。在这个框架中,我们可以获取加速度、步数等等等等运动数据,今天我们主要是讲讲步数是怎么获取的。

第一个我就不介绍了,网上有很多教程

简单的介绍下后两个吧。

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];


--------------------- 
作者:MooAiFighting 
来源:CSDN 
原文:https://blog.csdn.net/ZCMUCZX/article/details/78510948 
版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值