【问题标题】:CMStepCounter Adding Number of Steps to Separate NSIntegersCMStepCounter 添加步数以分隔 NSInteger
【发布时间】:2014-01-25 13:56:39
【问题描述】:
#import "CPPedometerViewController.h"
#import <CoreMotion/CoreMotion.h>

@interface CPPedometerViewController ()

@property (weak, nonatomic) IBOutlet UILabel *stepsCountingLabel;
@property (nonatomic, strong) CMStepCounter *cmStepCounter;
@property (nonatomic, strong) NSOperationQueue *operationQueue;
@property (nonatomic, strong) NSMutableArray *stepsArray;

@end

@implementation CPPedometerViewController

- (NSOperationQueue *)operationQueue
{
    if (_operationQueue == nil)
    {
        _operationQueue = [NSOperationQueue new];
    }
    return _operationQueue;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self QueryExistingStep];


    NSLog( @"steps array = %@", _stepsArray);

}

-(void)QueryExistingStep
{
    //get todays date
    NSDate *now = [NSDate date];
    // get six days ago from today
    NSDate *sixDaysAgo = [now dateByAddingTimeInterval:-6*24*60*60];

    //array to hold step values
    _stepsArray = [[NSMutableArray alloc] initWithCapacity:7];

    //check if step counting is avaliable
    if ([CMStepCounter isStepCountingAvailable])
    {
        //init step counter
        self.cmStepCounter = [[CMStepCounter alloc] init];

        //get seven days before from date & to date.
        for (NSDate *toDate = [sixDaysAgo copy]; [toDate compare: now] <= 0;
             toDate = [toDate dateByAddingTimeInterval:24 * 60 * 60] ) {

            //get day before
            NSDate *fromDate = [[toDate copy] dateByAddingTimeInterval: -1 * 24 * 60 * 60];

            [self.cmStepCounter queryStepCountStartingFrom:fromDate to:toDate toQueue:self.operationQueue withHandler:^(NSInteger numberOfSteps, NSError *error) {
                if (!error) {
                    NSLog(@"queryStepCount returned %ld steps", (long)numberOfSteps);
                    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                        [self updateArrayWithStepCounter:numberOfSteps];
                    }];
                } else {
                    NSLog(@"Error occured: %@", error.localizedDescription);
                }

            }];

        }
    } else {
        // stuffhappens
    }
}

- (void)updateArrayWithStepCounter:(NSInteger)numberOfSteps {

    [_stepsArray addObject:[NSNumber numberWithInteger:numberOfSteps]];
}

@end

我正在寻找一个包含过去 7 天的步骤的数组,然后将它们插入到每天的 NSinteger 中。例如NSInteger daySeven = 242,NSInteger daySix = 823 ... 今天也是如此。

但是,在退出 updateArrayWithStepCounter 方法后,数组似乎清除了。关于如何解决这个问题的任何想法,所以每个步骤也进入单独的 NSIntegers。谢谢,瑞恩。

编辑:

这里是 NSLog 输出:

2014-01-25 22:51:36.314 Project[6633:60b] steps array = (
)
2014-01-25 22:51:36.332 Project[6633:420f] queryStepCount returned 3505 steps
2014-01-25 22:51:36.334 Project[6633:420f] queryStepCount returned 3365 steps
2014-01-25 22:51:36.335 Project[6633:420f] queryStepCount returned 7206 steps
2014-01-25 22:51:36.337 Project[6633:420f] queryStepCount returned 6045 steps
2014-01-25 22:51:36.339 Project[6633:420f] queryStepCount returned 5259 steps
2014-01-25 22:51:36.342 Project[6633:420f] queryStepCount returned 6723 steps
2014-01-25 22:51:36.344 Project[6633:420f] queryStepCount returned 440 steps

这是建议的输出。正如您所看到的,它肯定会获取值,但是当它在运行该方法后检查数组时,它现在是空的。

我会不会错误地将它添加到数组中?

我希望这更清楚我很难过。谢谢

【问题讨论】:

    标签: ios objective-c nsmutablearray nsoperationqueue core-motion


    【解决方案1】:

    首先,这个输出是什么?

    NSLog(@"steps array = %@", _stepsArray);
    

    当有人问你某事时,你应该尝试用所要求的确切信息来回复,只是说“它说数组是空的”并没有帮助,因为也许有人可以看到你在输出中看不到的东西.

    说到这里,我会添加更多的 NSLog,因为可能是您的处理程序没有被调用,或者没有使用您期望的信息调用。

    使用以下命令,让我们知道输出:)

    [self.cmStepCounter queryStepCountStartingFrom:fromDate to:toDate toQueue:self.operationQueue withHandler:^(NSInteger numberOfSteps, NSError *error) {
        if (!error) {
            NSLog(@"queryStepCount returned %d steps", numberOfSteps);
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                [self updateArrayWithStepCounter:numberOfSteps];
            }];
        } else {
            NSLog(@"Error occured: %@", error.localizedDescription);
        }
    
    }];
    

    编辑:从新发布的 NSLog 输出中,我可以理解问题所在。事实是处理程序异步运行,这意味着您不能只在 viewDidLoad 上输出数组,因为它在数组收到所有值之前运行,因此您应该重构代码以在所有数据准备好时触发方法.

    这里对您的代码进行了更易读的修订(删除了一些无用的“复制”调用,更新了您的“条件”等),现在应该很容易理解发生了什么以及如何执行附加逻辑。

    #import "PYViewController.h"
    #import <CoreMotion/CoreMotion.h>
    
    @interface PYViewController ()
    
    @property (weak, nonatomic) IBOutlet UILabel *stepsCountingLabel;
    @property (nonatomic, strong) CMStepCounter *cmStepCounter;
    @property (nonatomic, strong) NSOperationQueue *operationQueue;
    @property (nonatomic, strong) NSMutableArray *stepsArray;
    
    @end
    
    @implementation PYViewController
    
    - (NSOperationQueue *)operationQueue {
        if (_operationQueue == nil) {
            _operationQueue = [NSOperationQueue new];
            _operationQueue.maxConcurrentOperationCount = 1; // process 1 operation at a time, or we could end with unexpected results on _stepsArray
        }
        return _operationQueue;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        [self queryExistingStep];
    }
    
    -(void)queryExistingStep {
        // Get now date
        NSDate *now = [NSDate date];
    
        // Array to hold step values
        _stepsArray = [[NSMutableArray alloc] initWithCapacity:7];
    
        // Check if step counting is avaliable
        if ([CMStepCounter isStepCountingAvailable]) {
            // Init step counter
            self.cmStepCounter = [[CMStepCounter alloc] init];
            // Tweak this value as you need (you can also parametrize it)
            NSInteger daysBack = 6;
            for (NSInteger day = daysBack; day > 0; day--) {
                NSDate *fromDate = [now dateByAddingTimeInterval: -day * 24 * 60 * 60];
                NSDate *toDate = [fromDate dateByAddingTimeInterval:24 * 60 * 60];
    
                [self.cmStepCounter queryStepCountStartingFrom:fromDate to:toDate     toQueue:self.operationQueue withHandler:^(NSInteger numberOfSteps, NSError *error) {
                    if (!error) {
                        NSLog(@"queryStepCount returned %ld steps", (long)numberOfSteps);
                        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                            [_stepsArray addObject:@(numberOfSteps)];
    
                            if ( day == 1) { // Just reached the last element, do what you want with the data
                                NSLog(@"_stepsArray filled with data: %@", _stepsArray);
                                // [self updateMyUI];
                            }
                        }];
                    } else {
                        NSLog(@"Error occured: %@", error.localizedDescription);
                    }                
                }];
            }
        } else {
            NSLog(@"device not supported");
        }
    }
    
    @end
    

    【讨论】:

    • 当它回到 viewDidLoad 方法时,_stepsArray 打印出空:(
    • 这并没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方发表评论 - 您可以随时评论自己的帖子,一旦您有足够的reputation,您就可以comment on any post
    • 我最初发送了一个问题,因为我没有足够的声誉来对他的问题发表评论。但是我只是扩展了我的答案:-)
    • 我已经添加了您建议的代码,并在编辑后的问题中显示了结果。它似乎可以很好地打印出值,但是它可能没有正确添加到数组中?
    • 这不应该总是正确的。是的,这些步骤在数组中,但也许它们的顺序不正确。为避免这种情况,您可以使用 _operationQueue.maxConcurrentOperationCount = 1; 对其进行序列化
    【解决方案2】:

    我要做的是等待数组获得所有需要的值,然后再做一些事情。它对我有用。

    - (void)queryPast6DayStepCounts
    {
       NSLog(@"queryPast6DayStepCounts visited!");
    
      self.past6DaysDailySteps = [[NSMutableArray alloc] initWithCapacity:6];
    
    // past 6 days
    
    for (NSInteger day = 6; day >= 1; day--)
    {
        NSDate *fromDate = [self.todayMidnight dateByAddingTimeInterval:-day * 24 * 60 * 60];
        NSDate *toDate = [fromDate dateByAddingTimeInterval:24 * 60 * 60];
    
        [self.cmStepCounter
         queryStepCountStartingFrom:fromDate to:toDate
         toQueue:[NSOperationQueue mainQueue]
         withHandler:^(NSInteger numberOfSteps, NSError *error)
         {
             if (!error)
             {
                     [self.past6DaysDailySteps addObject:@(numberOfSteps)];
                     if (self.past6DaysDailySteps.count == 6) {
                         [self viewDidFinishQueryPast6DaysData];
                     }
    
             }
             else
             {
                 NSLog(@"Error occured: %@", error.localizedDescription);
             }
         }
         ];
    
    }
     }
     -(void)viewDidFinishQueryPast6DaysData
      {
        NSLog(@"queryPast6DayStepCounts finish! %@", self.past6DaysDailySteps);
       // do other things
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-25
      • 2020-04-11
      • 2011-07-20
      • 2014-02-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多