Building, testing, & shipping My Cadence for iOS in less than a week
Tags: mobile, dotnet, xamarin
Published: 2020-12-24 20:08:21

---
title: Building, testing, & shipping My Cadence for iOS in less than a week
published: true
date: 2020-12-24 17:43:57 UTC
tags: mobile,dotnet,xamarin
canonical_url: https://montemagno.com/building-testing-shipping-my-cadence-for-ios-in-less-than-a-week/
---

 ![Building, testing, & shipping My Cadence for iOS in less than a week](https://montemagno.com/content/images/2020/12/image-28-1.png)

My [holiday hacking](https://devblogs.microsoft.com/xamarin/xamarin-holiday-season-hack-ideas/) came early this year when I decided to build my own [DIY spin bike](https://montemagno.com/building-an-at-home-diy-spin-bike-for-peloton-apple-fitness/). Soon, after a few rides, my mind started to swirl with app ideas of how to improve my ride. Then when Apple released Apple Fitness+ without support for displaying cadence information from sensors I knew I had to build an app. That app is [My Cadence](https://montemagno.com/introducing-my-cadence-for-ios-a-simple-cadence-sensor-display/), which connects to a small cadence sensor and displays the current cadence. It is actually packed full of awesome features including custom themes, in-app purchases, store reviews, and more! Best of all it only took me around 12 hours to develop, test, and ship during the last week since I started it. So, today I want to walk through all of the features I put in and how I developed them.

{% youtube evctpFybZBY %}


## Xamarin.Forms 5

With [Xamarin.Forms 5](https://github.com/xamarin/xamarin.forms) nearing stable release it was the first thing I updated to when I created the project. I leveraged a lot of new features such as [embedded fonts](https://docs.microsoft.com/xamarin/xamarin-forms/user-interface/text/fonts), [App Themes for Light/Dark mode](https://docs.microsoft.com/xamarin/xamarin-forms/user-interface/theming/), [gradient brushes](https://docs.microsoft.com/xamarin/xamarin-forms/user-interface/brushes/gradient), [geometry clipping](https://docs.microsoft.com/xamarin/xamarin-forms/user-interface/shapes/geometries), and a bunch more! I love how easy it is to react to the mode change on the user's device with a simple line of code.

```
 <Label Text="The following sensors have been tested with My Cadence."
        TextColor="{AppThemeBinding Dark=White, Light=Black}"/>
```

Here is a bit of the app themes in action:

![Building, testing, & shipping My Cadence for iOS in less than a week](https://montemagno.com/content/images/2020/12/AppTheme-1.gif)

## Bluetooth

The cadence sensor broadcast over Bluetooth Low Energy. This was actually the first time that I had worked with Bluetooth and I leveraged the [Plugin.BLE](https://github.com/xabre/xamarin-bluetooth-le) library to easily detect, connect, and read data from the device. I may upgrade to [Shiny](https://github.com/shinyorg/shiny) in the future, but this was the first one I grabbed and it has been working well.

I fell in love so much with Bluetooth that Frank and I recorded a full [Merge Conflict podcast](https://www.mergeconflict.fm/233) on it!

## In-app Purchases

I decided to add a "Pro" mode into the application at the last minute. My thought was that the entire app would be free without restrictions, but to help support the app a user could upgrade to "Pro" to unlock custom theming in the app. I leveraged my [InAppBilling plugin](https://github.com/jamesmontemagno/InAppBillingPlugin) and had the upgraded implemented in about 30 minutes. Here is the code from the app if you are interested in how easy it is to implement.

```
const string productId = "pro";

async Task PurchasePro()
{
    if (IsBusy)
        return;

    IsBusy = true;

    try
    {
        if(Connectivity.NetworkAccess != NetworkAccess.Internet)
        {
            await DisplayAlert("No internet", "Please check internet connection and try purchase again.", "OK");
            return;
        }

        var connected = await CrossInAppBilling.Current.ConnectAsync();

        if (!connected)
        {
            await DisplayAlert("Unable to Connect", "Unable to connect to the app store, check your internet connectivity and try again.", "OK");
            return;
        }

        //check purchases
        var purchase = await CrossInAppBilling.Current.PurchaseAsync(productId, ItemType.InAppPurchase);

        if (purchase == null)
        {
            return;
        }
        else if (purchase.State == PurchaseState.Purchased)
        {
            Settings.IsPro = true;
            SetPro();
            return;
        }

        throw new InAppBillingPurchaseException(PurchaseError.GeneralError);

    }
    catch (InAppBillingPurchaseException purchaseEx)
    {
        var message = string.Empty;
        switch (purchaseEx.PurchaseError)
        {
            // figureout error message
        }

        if (string.IsNullOrWhiteSpace(message))
            return;

        Console.WriteLine("Issue connecting: " + purchaseEx);
        await DisplayAlert("Uh Oh!", message, "OK");
    }
    catch (Exception ex)
    {
        // Handle Exception
    }
    finally
    {
        await CrossInAppBilling.Current.DisconnectAsync();
        IsBusy = false;
    }
}

```

## Store Reviews

On thing that I always forget to put in my app is a way to prompt the user to review the application. Another one of my random plugins comes in to save the day, the [Store Review Plugin](https://github.com/jamesmontemagno/storereviewplugin)! In the settings screen I added a button to review the app:

```
void TextCellReview_Tapped(System.Object sender, System.EventArgs e)
{
    CrossStoreReview.Current.OpenStoreReviewPage("1545730360");
}
```

Then I also decided to do a prompt for the user to review after they use the app 5 times successfully.

```
var count = Settings.Usage;
count++;
if(count == 5)
{
    CrossStoreReview.Current.RequestReview(false);
}
Settings.Usage = count;
```

## Custom Controls

I surprisingly I only used 1 custom control in the entire app and it was available directly on [NuGet](https://www.nuget.org/packages/Spillman.Xamarin.Forms.ColorPicker/)! This control was an advanced color picker and I landed on one built by Dalton Spillman. It is fantastic as it allows full fidelity of color selection and has a built in ViewModel that works great for getting and setting colors.

![Building, testing, & shipping My Cadence for iOS in less than a week](https://montemagno.com/content/images/2020/12/Color-Picker.gif)

You can find the code to the control on [GitHub](https://github.com/daltonks/Spillman.Xamarin.Forms.ColorPicker).

## Xamarin.Essentials 

Wow, [Xamarin.Essentials](https://docs.microsoft.com/xamarin/essentials/) continues to make me super productive over and over and over again. I leveraged:

- Version Tracking
- Preferences
- Connectivity
- MainThread
- and more!

Every time I thought I was going to need to write some custom code Xamarin.Essetials was there.

## CI & CD

In one of my late night code sessions I decided to setup [App Center](https://appcenter.ms) Build/Distribute on the app and I am so glad I did. It took seconds to setup and I had things automatically building, versioning, and distributing to TestFlight in under 10 minutes!

![Building, testing, & shipping My Cadence for iOS in less than a week](https://montemagno.com/content/images/2020/12/image-29.png)

## More!

There is a lot more that went into this application outside of just the code. I generated a full [website](https://www.mycadence.app) and app screenshots from [http://apptoolkit.io/](http://apptoolkit.io/), created an app icon from [EasyAppIcon.com](https://easyappicon.com/), & had some amazing tester on Twitter using TestFlight.  

![Building, testing, & shipping My Cadence for iOS in less than a week](https://montemagno.com/content/images/2020/12/image-28.png)<figcaption>Thanks Dan for Testing!</figcaption>

## Available Now & OSS Code Soon

It is now available in the [App Store](https://apps.apple.com/app/id1545730360) completely for free! Soon the app is coming to Android as well as I just need to tweak a few Android specific settings and get it through the review process.

If you are looking to get into spinning checkout my [full blog on building a DIY spin bike](https://montemagno.com/building-an-at-home-diy-spin-bike-for-peloton-apple-fitness/).

Finally, I do plan on putting the full source code online, so be sure to check back when I write up a blog on it.