使用CMPedometer进行实时更新(CoreMotion)

我发现这个主题的资源非常有限(CMPedometer)。 我想知道这里是否有人设法让这个正常工作。 我的代码相当简单,并且比我正在尝试的更多。 基本上,步数计数器不会增加用户采取的每个步骤。

它实际上是跟踪用户采取的每一步,但它更新得如此缓慢,我无法弄清楚原因。 我甚至尝试使用NSTimer来请求每半秒更新一次标签。 我想尝试让步骤计数器在用户采取步骤时进行更新。 这是我的代码……

#import "ViewController.h" #import  @interface ViewController () @property (nonatomic, strong) CMPedometer *pedometer; @property (nonatomic, weak) IBOutlet UILabel *startDateLabel; @property (nonatomic, weak) IBOutlet UILabel *endDateLabel; @property (nonatomic, weak) IBOutlet UILabel *stepsLabel; @property (nonatomic, weak) IBOutlet UILabel *distanceLabel; @property (nonatomic, weak) IBOutlet UILabel *ascendedLabel; @property (nonatomic, weak) IBOutlet UILabel *descendedLabel; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; if ([CMPedometer isStepCountingAvailable]) { self.pedometer = [[CMPedometer alloc] init]; [NSTimer scheduledTimerWithTimeInterval:0.5f target:self selector:@selector(recursiveQuery) userInfo:nil repeats:YES]; } else { NSLog(@"Nothing available"); self.startDateLabel.text = @""; self.endDateLabel.text = @""; self.stepsLabel.text = @""; self.distanceLabel.text = @""; self.ascendedLabel.text = @""; self.descendedLabel.text = @""; } } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.pedometer startPedometerUpdatesFromDate:[NSDate date] withHandler:^(CMPedometerData *pedometerData, NSError *error) { dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"data:%@, error:%@", pedometerData, error); }); }]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self.pedometer stopPedometerUpdates]; } - (NSString *)stringWithObject:(id)obj { return [NSString stringWithFormat:@"%@", obj]; } - (NSString *)stringForDate:(NSDate *)date { NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; formatter.dateStyle = NSDateFormatterShortStyle; formatter.timeStyle = NSDateFormatterShortStyle; return [formatter stringFromDate:date]; } - (void)queryDataFrom:(NSDate *)startDate toDate:(NSDate *)endDate { [self.pedometer queryPedometerDataFromDate:startDate toDate:endDate withHandler: ^(CMPedometerData *pedometerData, NSError *error) { NSLog(@"data:%@, error:%@", pedometerData, error); dispatch_async(dispatch_get_main_queue(), ^{ if (error) { NSLog(@"Error = %@",error.userInfo); self.startDateLabel.text = @""; self.endDateLabel.text = @""; self.stepsLabel.text = @""; self.distanceLabel.text = @""; self.ascendedLabel.text = @""; self.descendedLabel.text = @""; } else { self.startDateLabel.text = [self stringForDate:pedometerData.startDate]; self.endDateLabel.text = [self stringForDate:pedometerData.endDate]; self.stepsLabel.text = [self stringWithObject:pedometerData.numberOfSteps]; self.distanceLabel.text = [NSString stringWithFormat:@"%.1f[m]", [pedometerData.distance floatValue]]; self.ascendedLabel.text = [self stringWithObject:pedometerData.floorsAscended]; self.descendedLabel.text = [self stringWithObject:pedometerData.floorsDescended]; } }); }]; } - (void)recursiveQuery { NSDate *to = [NSDate date]; NSDate *from = [to dateByAddingTimeInterval:-(24. * 3600.)]; [self queryDataFrom:from toDate:to]; } 

提前感谢您的任何反馈!

编辑

似乎用于实时更新的适当方法如下..

 - (void)liveSteps { [self.pedometer startPedometerUpdatesFromDate:[NSDate date] withHandler:^(CMPedometerData *pedometerData, NSError *error) { dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"Steps %@",pedometerData.numberOfSteps); }); }]; } 

然而,即使这种情况严重延迟。 有没有人知道如何正确使用它来实质上更新,因为用户采取了一个步骤?

我只能确认你的发现。 我也希望获得“真实”的实时信息。 就像在这一点上看来,API无法做到这一点; 甚至通过强制更新队列,同步,异步等。

对于有这个问题的参考和其他人,这里是我使用的基于Swift 3和Xcode 8.2的代码。 在检查CMPedometer.isStepCountingAvailable()之后,我只是在相关的viewcontroller中应用这部分代码。

如您所见,我已经包含了一个小动画,以更流畅的方式更新UILabel。

  // Steps update in near realtime - UILabel self.pedoMeter.startUpdates(from: midnightOfToday) { (data: CMPedometerData?, error) -> Void in DispatchQueue.main.async(execute: { () -> Void in if(error == nil){ self.todaySteps.text = "\(data!.numberOfSteps)" // Animate the changes of numbers in the UILabel UILabel.transition(with: self.todaySteps, duration: 0.50, options: .transitionCrossDissolve, animations: nil, completion: nil) } }) }