Живые обновления с CMPedometer (CoreMotion)
Я нашел очень ограниченные ресурсы по этой теме (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);
});
}];
}
Однако даже это сильно задерживается. Кто-нибудь имеет какие-либо идеи, как использовать это правильно, чтобы существенно обновить, как пользователь делает шаг?
1 ответ
Я могу только подтвердить ваши выводы. Я также хотел получить "правдивую" информацию в реальном времени. Как кажется на данный момент, API не способен на это; даже путем принудительного обновления в очередь, синхронизации, асинхронности и т. д.
Для ссылок и других с этим вопросом, вот код, который я использую, основанный на Swift 3 и Xcode 8.2. Я просто применяю эту часть кода в соответствующем viewcontroller, после проверки CMPedometer.isStepCountingAvailable().
Как вы можете видеть, я включил небольшую анимацию, чтобы обновить 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)
}
})
}