Search code examples
swiftcore-motion

Swift await for async request to complete


I have the following function by which I want to return a Int

  private func queryPedometerSteps(currentStartDate: Date, currentLastDate: Date) -> Int {
    var stepsGiven = 0
    pedometer.queryPedometerData(from: currentStartDate, to: currentLastDate){data, error in
      guard let pedometerData = data else { return }
      let steps = pedometerData.numberOfSteps.intValue
      print("entered query from \(currentStartDate) to \(currentLastDate) and stepped \(steps)")
      stepsGiven = steps
    }
    return stepsGiven
  }

I am using this function to return the steps, by which is assigned to a variable and then use it for another function, like this

let numberOfStepsBetweenDates = queryPedometerSteps(currentStartDate: currentStartDate, currentLastDate: currentLastDate)
anotherCall(numberOfStepsBetweenDates: Int)

I want the pedometer.queryPedometerData to finish before returning the stepsGiven. The code as it is, the function always returns 0. I already tried Dispatch groups, and semaphores, but for some reason the code stops working when I use these. Does somebody have any idea how to accomplish this? Thanks!!!


Solution

  • Change the function like so:

    private func queryPedometerSteps(currentStartDate: Date, 
                                     currentLastDate: Date,
                                     completion: (Int?) -> Void) {
      pedometer.queryPedometerData(from: currentStartDate, to: currentLastDate) { data, error in
        guard let pedometerData = data else { return completion(nil) }
        let steps = pedometerData.numberOfSteps.intValue
        print("entered query from \(currentStartDate) to \(currentLastDate) and stepped \(steps)")
        completion(steps)
      }
    }
    

    your calling code will then look like this:

    queryPedometerSteps(currentStartDate: currentStartDate, currentLastDate: currentLastDate) { steps in 
      guard let steps = steps else { return }
      anotherCall(numberOfStepsBetweenDates: steps)
    }
    

    (you may have to mark the closures as @escaping - I haven't checked the Pedometer API)