iosswiftcore-motion

How to use CMPedometer on an iPad?


I have been exploring pedometers and playing around with a simple app that counts your steps. This works perfectly on the iPhone however when run on an iPad it fails to count any steps.

I have imported CoreMotion and add a usage description.

Is there any reason as to why the app isn't working on the iPad?

@IBAction func startStopButton(_ sender: UIButton) {
    if sender.titleLabel?.text == "Start"{
        //Start the pedometer
        stepsLabel.text = "Steps: 0"
        distanceLabel.text = "Distance: N/A"
        
        pedometer = CMPedometer()
        startTimer()
        pedometer.startUpdates(from: Date(), withHandler: { (pedometerData, error) in
            if let pedData = pedometerData{
                self.numberOfSteps = Int(truncating: pedData.numberOfSteps)
                //self.stepsLabel.text = "Steps:\(pedData.numberOfSteps)"
                if let distance = pedData.distance{
                    self.distance = Double(truncating: distance)
                }
                if let averageActivePace = pedData.averageActivePace {
                    self.averagePace = Double(truncating: averageActivePace)
                }
                if let currentPace = pedData.currentPace {
                    self.pace = Double(truncating: currentPace)
                }
            } else {
                self.numberOfSteps = nil
            }
        })
        //Toggle the UI to on state
        statusTitle.text = "Pedometer On"
        sender.setTitle("Stop", for: .normal)
        sender.backgroundColor = stopColor
    } else {
        //Stop the pedometer
        pedometer.stopUpdates()
        stopTimer()
        //Toggle the UI to off state
        statusTitle.text = "Pedometer Off: "
        sender.backgroundColor = startColor
        sender.setTitle("Start", for: .normal)
    }
}

//MARK: - timer functions
func startTimer(){
    if timer.isValid { timer.invalidate() }
    timer = Timer.scheduledTimer(timeInterval: timerInterval,target: self,selector: #selector(timerAction(timer:)) ,userInfo: nil,repeats: true)
}
 
func stopTimer(){
    timer.invalidate()
    displayPedometerData()
    
    if let distance = self.distance {
        
        let milesString = (String(format: "%.2f", self.miles(meters: self.distance)))
    
    let alert = UIAlertController(title: "Save your distance of \(milesString) Miles", message: "You can add the counted distance to all runners now or add them individually by swiping them right on the home screen and adding lap. This will add the distance to the runner you select.", preferredStyle: UIAlertController.Style.alert)
             // add an action (button)
            alert.addAction(UIAlertAction(title: "Add to all", style: UIAlertAction.Style.default, handler: { action in
             
                
                for index in self.distancesArray.indices {
                    self.distancePerLapMiles = self.miles(meters: self.distance)
                    self.distancesArray[index] += self.distancePerLapMiles
                    print("index is \(index)")
                }
                
                self.tableView.reloadData()
                self.saveData()
                
                self.allViewsOff()
              
                 }))
            alert.addAction(UIAlertAction(title: "Add Individually", style: UIAlertAction.Style.default, handler: { action in
                    
                self.distancePerLapMiles = self.miles(meters: self.distance)
                self.allViewsOff()
                          
                             }))

        alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel, handler: nil))
    
            self.present(alert, animated: true, completion: nil)
        
    }
}
 
@objc func timerAction(timer:Timer){
    displayPedometerData()
}
// display the updated data
func displayPedometerData(){
    timeElapsed += 1.0
    statusTitle.text = "Steps are being Counted"
    //Number of steps
    if let numberOfSteps = self.numberOfSteps{
        stepsLabel.text = String(format:"Steps: %i",numberOfSteps)
    }
    //distance
    if let distance = self.distance{
        distanceLabel.text = String(format:"Distance: \n \n %02.02f meters,\n \n %02.02f miles",distance,miles(meters: distance))
    } else {
        distanceLabel.text = "Distance: N/A"
    }
}
 
//MARK: - Display and time format functions
 
// convert seconds to hh:mm:ss as a string
func timeIntervalFormat(interval:TimeInterval)-> String{
    var seconds = Int(interval + 0.5) //round up seconds
    let hours = seconds / 3600
    let minutes = (seconds / 60) % 60
    seconds = seconds % 60
    return String(format:"%02i:%02i:%02i",hours,minutes,seconds)
}
// convert a pace in meters per second to a string with
// the metric m/s and the Imperial minutes per mile

func miles(meters:Double)-> Double{
    let mile = 0.000621371192
    return meters * mile
}

Solution

  • Not all devices have the required hardware to support step counting.

    You should check the value of isStepCountingAvailable. If it returns false then step counting is not available on the device.