We will be building a simple step counter app which uses a pedometer data to retrieve step counts and other information about the distance traveled and the number of floors ascended or descended. The pedometer object manages a cache of historic data that you can query or you can ask for live updates as the data is processed.

The CMMotionActivity class contains the data for a single motion update event. On devices that support motion, you can use a CMMotionActivityManager object to request updates when the current type of motion changes. When a change occurs, the update information is packaged into a CMMotionActivity object and sent to your app.

CMMotionActivity contains state related to many of the activites like stationary, walking, running, automative, cycling and unknown. Also along with that it provides confidence about how accurate the motion data is.

CMPedoMeter and CMMotionActivityManager will work on actual devices.

In the mainstory board let go ahead and start adding the UILabel’s and UIImageview.

Add Labels for the Today , Steps , Activity state.

, , state. Add imageview for the shoe and the state ( Either running, walking, stationary,automotive )

) Setup the IBOutlet for all the above.

for all the above. More on autolayouts AutoLayout Part 1 and Autolayout part 2

There are multiple ways we can query the data from the CMPedometer and the CMActivityManager.

Realtime push as the events happen

Query cached data with start and end date.

In this app I am currently using both of the above methods. When the app starts up I fetch the data from midnight till now to get the steps for today and update the View.

self.pedoMeter.queryPedometerDataFromDate(midnightOfToday, toDate: NSDate())

Along with we utilize the realtime push from the framework to show the latest steps and the current activity.

self.pedoMeter.startPedometerUpdatesFromDate(midnightOfToday)

// // ViewController.swift // Steps // // Created by Shrikar Archak on 4/11/15. // Copyright (c) 2015 Shrikar Archak. All rights reserved. // import UIKit import CoreMotion class ViewController: UIViewController { @IBOutlet weak var activityState: UILabel! @IBOutlet weak var steps: UILabel! var days:[String] = [] var stepsTaken:[Int] = [] @IBOutlet weak var stateImageView: UIImageView! let activityManager = CMMotionActivityManager() let pedoMeter = CMPedometer() override func viewDidLoad() { super.viewDidLoad() let cal = NSCalendar.currentCalendar() var comps = cal.components(NSCalendarUnit.YearCalendarUnit | .MonthCalendarUnit | .DayCalendarUnit | .HourCalendarUnit | .MinuteCalendarUnit | .SecondCalendarUnit, fromDate: NSDate()) comps.hour = 0 comps.minute = 0 comps.second = 0 let timeZone = NSTimeZone.systemTimeZone() cal.timeZone = timeZone let midnightOfToday = cal.dateFromComponents(comps)! if(CMMotionActivityManager.isActivityAvailable()){ self.activityManager.startActivityUpdatesToQueue(NSOperationQueue.mainQueue(), withHandler: { (data: CMMotionActivity!) -> Void in dispatch_async(dispatch_get_main_queue(), { () -> Void in if(data.stationary == true){ self.activityState.text = "Stationary" self.stateImageView.image = UIImage(named: "Sitting") } else if (data.walking == true){ self.activityState.text = "Walking" self.stateImageView.image = UIImage(named: "Walking") } else if (data.running == true){ self.activityState.text = "Running" self.stateImageView.image = UIImage(named: "Running") } else if (data.automotive == true){ self.activityState.text = "Automotive" } }) }) } if(CMPedometer.isStepCountingAvailable()){ let fromDate = NSDate(timeIntervalSinceNow: -86400 * 7) self.pedoMeter.queryPedometerDataFromDate(fromDate, toDate: NSDate()) { (data : CMPedometerData!, error) -> Void in println(data) dispatch_async(dispatch_get_main_queue(), { () -> Void in if(error == nil){ self.steps.text = "\(data.numberOfSteps)" } }) } self.pedoMeter.startPedometerUpdatesFromDate(midnightOfToday) { (data: CMPedometerData!, error) -> Void in dispatch_async(dispatch_get_main_queue(), { () -> Void in if(error == nil){ self.steps.text = "\(data.numberOfSteps)" } }) } } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } }