CMPedometer queryPedometerData() returning 0 steps when steps exist

1.1k views Asked by At

There seems to be a bug in the CMPedometer queryPedometerData() method. The method is returning 0 steps for certain end times, but the same query with the timestamp 1 second higher or lower returns the correct number of steps

e.g.

self.getStepsBetweenDates(NSDate(timeIntervalSince1970: 1543392126) as Date, date2:  NSDate(timeIntervalSince1970: 1543393044) as Date) returns (Int) 1488

self.getStepsBetweenDates(NSDate(timeIntervalSince1970: 1543392126) as Date, date2:  NSDate(timeIntervalSince1970: 1543393045) as Date) returns (Int) 0

self.getStepsBetweenDates(NSDate(timeIntervalSince1970: 1543392126) as Date, date2:  NSDate(timeIntervalSince1970: 1543393046) as Date) returns (Int) 1488

getStepsBetweenDates method looks like this

func getStepsBetweenDates(_ date1: Date, date2: Date) -> Int{

    let group = DispatchGroup()
    group.enter()

    var steps = 0

    self.pedometer.queryPedometerData(from: date1, to: date2, withHandler: {
      pData, error in
      if let e = error{
          print("Error querying pedometer", e.localizedDescription)
      }else{
        if let data = pData{
          steps = Int(data.numberOfSteps)
        }
        group.leave()
      }
    })

    _ = group.wait(timeout: DispatchTime.distantFuture)
    return steps

  }
1

There are 1 answers

1
Chris On BEST ANSWER

queryPedometerData is an asynchronous call

Ordinarily you would not want to return the steps in the getStepsBetweenDates call because it is asynchronous.

If you changed the var steps = 0 to var steps = [some random int] then it's likely you'll get that number back instead of 0 because of the race condition set up.

More ideally would be to implement your code as a closure/callback or another form of asynchronous handling.

eg:

self.pedometer.queryPedometerData(from: date1, to: date2) { (data, error) in
  // Do something here with data.numberOfSteps    
}

Here's an article on Medium about async code:

https://medium.com/ios-os-x-development/managing-async-code-in-swift-d7be44cae89f