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

标签 ios objective-c core-motion

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

它实际上在跟踪用户的每一步,但更新速度如此之慢,我不明白为什么。我什至尝试使用 NSTimer 请求每半秒更新一次标签。我想尝试让计步器在用户迈出一步时更新。这是我的代码...

#import "ViewController.h"
#import <CoreMotion/CoreMotion.h>

@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() 之后,我只是将这部分代码应用到相关的 View Controller 中。

如您所见,我添加了一个小动画以更流畅的方式更新 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)
            }
        })
    }

关于ios - 使用 CMPedometer (CoreMotion) 进行实时更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36439912/

相关文章:

iphone - CMDeviceMotion 用户加速度漂移

ios - 页脚 View 颜色总是比 UITableView 分隔符颜色深

ios - 如何在 Objective C 中正确使用接口(interface)作为 DTO

ios - 代码 "The private key for is not installed on this mac - distributing"

iphone - 如何在选择器 View 列表更新时获取调用的函数?

ios - 如何在 Storyboard 中的 UITableViewController 底部添加工具栏?

android-studio - Android Studio 找不到 MotionLayout 的类

iphone - 在iPhone5S中使用M7芯片

ios - 在 Watch App 中创建进度圈作为 WKInterfaceImage

ios - 将相机图像抖动到 swift UIimage