2016-04-06 20 views
4

Bu konuyla ilgili çok sınırlı kaynak buldum (CMPedometre). Buradaki herkesin düzgün çalışması için bunu başarmış olup olmadığını merak ediyordum. Kodum oldukça basit ve yapmaya çalıştığımdan daha fazlasına sahip. Temel olarak, adım sayacı bir kullanıcının aldığı HER adımı artırmaz.CMPedometer (CoreMotion) ile Canlı Güncellemeler

Aslında kullanıcının aldığı her adımı izliyor, ancak çok yavaş güncelleştiriyor ve nedenini anlayamıyorum. Etiketleri her yarım saniyede bir güncellemek için NSTimer kullanmayı denedim bile. Bir kullanıcı adım atarken güncellemek için adım sayacı almaya çalışıyorum. İşte benim kodum ...

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

Herhangi bir geri bildiriminiz için şimdiden teşekkür ederiz!

DÜZENLEME

Canlı güncellemeler için kullanılacak uygun yöntemi görünse de bu ciddi gecikir, Ancak şu ..

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

olduğunu. Kullanıcı bir adım atarken esasen güncellemek için bunu düzgün kullanmanın herhangi bir fikri var mı?

+0

Buna bir yanıt buldunuz mu? –

+0

Hayır, asla. Denemeyi bıraktım ve devam ettim –

cevap

3

Yalnızca bulgularınızı onaylayabilirim. Ayrıca "gerçek" gerçek zamanlı bilgi almak istedim. Bu noktada göründüğü gibi, API bu yeteneğe sahip değildir; güncellemeleri bir sıraya, senkronizasyona, uyumsuzluğa vb. zorlamak suretiyle bile.

Bu soruyla ilgili referanslar ve diğerleri için, burada Swift 3 ve Xcode 8.2'ye dayalı olarak kullandığım kod. Ben CMPedometer.isStepCountingAvailable() kontrol ettikten sonra ilgili viewcontroller kodun bu kısmını uygula.

Gördüğünüz gibi UILabel'i daha akıcı bir şekilde güncellemek için küçük bir animasyon ekledim.

// 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) 
      } 
     }) 
    } 
İlgili konular