Cross Platform C#

Track Your Fitness with a Fitbit and Xamarin

Wally shows you how to use Xamarin.iOS to create a pedometer app for a Fitbit that employs the CoreMotion Framework.

I’ve been a Fitbit user for several years. I enjoy using it, reading the material and hoping that if I push myself it will help my level of fitness (probably not). What I don’t like is that:

  • It’s another device that I have to keep track of. Sure, it's on my wrist, but I still have to maintain it.
  • I have to keep it charged. My current daily driver is a Fitbit Charge2 that holds a charge for seven days – that's great, but it still has to be charged. So, I also have to keep track of a charger, which adds to the hassle.

Those two things aside, I've found that the device's usefulness far outweighs the hassles. I've even developed a pedometer app for it, which I'll show in this column.

The app uses the CoreMotion iOS framework, which is used for determining number of steps walked/run.

Note No. 1: It will be a hassle to do some things with the iPhone. For example, trying to determine the number of steps taken while riding a bicycle will be somewhat problematic. You will be able to do other things with the iPhone, such as determine the distance traveled and such.

Note No. 2: This article features a native application using Xamarin.iOS.

CoreMotion
CoreMotion is an iOS framework that allows an application to receive information regarding the motion of the device and to then process that data. The framework contains a number of classes that allow it to access the motion events, including:

  • CMAltimeter: Handles altitude-related information.
  • CMDeviceMotion: Provides a set of measurements for the altitude, rotation rate and acceleration of a device
  • CMMotionActivityManager: Provides access to the motion data that’s stored in a device. With this data, it can be determined if the user with the phone is walking, running, not moving, in a moving car and so on.
  • CMMotionManager: As the gateway to the motion services, an application can determine the accelerometer, rotation rate, compass data and other motion information using this class.
  • CMPedometer: Allows an application to track the step data the phone’s user goes through.
  • CMSensorRecorder: Controls the gathering and recording of accelerometer data in a device.

There are additional classes, constants and other objects within CoreMotion, but this is just a quick overview of some of the objects that are available.

Hardware Requirements
There are a number of devices out in the iOS ecosystem. Not all of these devices are the most up-to-date. Does anyone really remember what the iPhone 5 supports? Instead of hardcoding in the application the devices and what they support, a better option is built into CoreMotion. CoreMotion allows you to query the device to see if it supports a given feature. Some of the features that are possible to query for are:

  • IsCadenceAvailable
  • IsDistanceAvailable
  • IsFloorcountingAvailable
  • IsPaceAvailable
  • IsStepCountingAvailable

Thanks to these methods, an application merely calls these static methods on the CMPedometer class to determine what functionality is available on the specific hardware. These methods return true if the device supports the functionality and false if the device doesn’t support it.

Underneath iOS, there’s some hardware to provide support for these iOS calls. The hardware is the Apple motion coprocessors. The motion coprocessor, called the M7, was introduced with the iPhone 5s. Each new version of the iPhone has received an updated coprocessor. The coprocessors collect data even if the device is asleep. This reduces the power needed from the battery.

Note: To make a call into the hardware, the application will most likely need to have a security entry in the Info.plist file. For this specific example, you will need to set "Privacy - Motion Usage Description" to a value of YES.

Note: You will need to specify the reason for using motion data. This is done by setting the NSMotionUsageDescription in the Info.plist file.

Exercise That Code
Let’s take a look at some example code (Listing 1). In this code, a very simple UI is created with two labels. One label shows the number of steps that have been taken in the last 24 hours, and the other shows the phone’s current pace.

The code in Listing 1 itself is fairly simple. After the UI is created, a CMPedometer instance is created, and then a test is made of the device to see if it will support pedometer events. If that’s true, the number of steps taken in the previous 24 hours is determined. Finally, the current rate is displayed.

Listing 1: Pedometer UI Using CoreMotion
public override void ViewDidLoad()
{
  base.ViewDidLoad();
  uil = new UILabel();
  var vwFrame = this.View.Frame;
  uil.Frame = new CoreGraphics.CGRect(10.0, 50.0, vwFrame.Width - 20.0, 25.0);
  this.View.Add(uil);
  uilNow = new UILabel();
  uilNow.Frame = new CoreGraphics.CGRect(10, 85.0, vwFrame.Width - 20.0, 25);
  this.View.Add(uilNow);
  cmp = new CoreMotion.CMPedometer();
}
public override async void ViewDidAppear(bool animated)
{
  base.ViewDidAppear(animated);

  if (CoreMotion.CMPedometer.IsPedometerEventTrackingAvailable)
  {
    cmp.StartPedometerUpdates(new Foundation.NSDate(), handlePedoUpdates);

    var pedData = await cmp.QueryPedometerDataAsync((new Foundation.NSDate()).AddSeconds(
      -86400), new Foundation.NSDate());
    uil.Text = String.Format("Last 24 hours: {0}", pedData.NumberOfSteps);
  }
}
public override void ViewDidDisappear(bool animated)
{
  base.ViewDidDisappear(animated);
  if (CoreMotion.CMPedometer.IsPedometerEventTrackingAvailable)
  {
    cmp.StopPedometerUpdates();
  }
}
private void handlePedoUpdates(CMPedometerData data, Foundation.NSError error)
{
  if(error == null)
  {
    InvokeOnMainThread(() => {
      uilNow.Text = String.Format("Pace; {0}", data.CurrentPace);
    });
  }
} 

The result of running this code and displaying it on an iPhone 7+ is shown in Figure 1, which shows that the phone had approximately 4,700 steps in the past 24 hours and was currently moving at a pace of about .86 meters per second. For this phone, that’s approximately correct. It also shows the most recent set of steps with the phone and the current pace of the device.

[Click on image for larger view.] Figure 1. Pedometer App Basic UI

So, what should you do with this data? There are multiple options. Some of these are:

  • Leave the content on the iPhone. There’s nothing wrong with leaving it on the phone and using it for future reference.
  • Store the information in some type of database out on the Web. This would allow for easy cross-platform reporting on it.
  • One of the ideas that I have always had is to use the information from movement in the health sciences area. Doctors could use this to determine the actual amount of aerobic exercise that patients were getting and prescribe necessary changes for a healthier outcome.
  • Gym/fitness clubs and trainers could use this for assisting their customers, as well.

Note: There may be legal or ethical questions in using this data and with where it’s shared. I hope that organizations would consult their legal departments regarding how to use this data. No statement here is an indication that this meets any legal requirement.

Wrapping Up
Xamarin.iOS provides access to all of the features of the device. It’s fairly easy to access anything associated with the published iOS API. The Pedometer is one of these features that allows an application to provide a very personal experience to the phone’s owner.

Good luck!

About the Author

Wallace (Wally) B. McClure has authored books on iPhone programming with Mono/Monotouch, Android programming with Mono for Android, application architecture, ADO.NET, SQL Server and AJAX. He's a Microsoft MVP, an ASPInsider and a partner at Scalable Development Inc. He maintains a blog, and can be followed on Twitter.

comments powered by Disqus

Featured

  • Using Local AI to Cut Copilot Usage-Based Billing Shock

    After being gobsmacked by the new billing plan using almost all my monthly credits in one or two days, I tried pushing some Copilot-style coding work onto local models in VS Code. What I found was less "free AI" and more "pick your pain": cloud charges on one side, heavy local resource use and long waits on the other.

  • .NET 11 Preview 5 Focuses on Performance, Productivity and Safer Code

    .NET 11 Preview 5 focuses on under-the-hood runtime performance gains, streamlined APIs and language features that reduce boilerplate, plus built‑in security checks and incremental ASP.NET Core and EF Core improvements aimed at everyday developer productivity.

  • VS Code 1.124 Focuses on Agent Autonomy and Parallel Sessions

    Microsoft's June 2026 VS Code update turns on Autopilot by default and adds background sending for agent sessions.

  • Developing Agentic Systems in .NET: From Concept to Code

    ZioNet founder Alon Fliess previews his Visual Studio Live! San Diego session on building true agentic systems in .NET -- covering the cognitive loop, MCP tool integration, multi-agent orchestration and enterprise hosting and governance with the Microsoft Agent Framework.

Subscribe on YouTube