Build a Xamarin.Forms iOS mobile app using Azure DevOps

I have been setting up the Azure DevOps builds required for our new mobile app. One for Android and one for iOS. In this article I will focus on the iOS app as this is the one that caused me the most difficulty. There is a degree more difficulty when developing for the Apple platform as you need to have a Mac, certificates and provisioning profiles, so configuring a build for iOS is a little more complex. This is definitely borne out by the number of Stackoverflow posts I found on the various issues I encountered.

Before proceeding, I want to fully clarify something that caught me out. This may seem self evident, but judging by the posts I came across on this issue, perhaps not so much. When running your iOS app from Visual Studio there are two methods of provisioning the app.

- Automatic provisioning — This is useful during development. You need to install a Mac onto your network that is visible to your Visual Studio environment and pair with it. Your Visual Studio environment will then read the necessary provisioning information directly from the Mac (be sure to disable the screen-saver on the Mac or else you’ll lose your pairing with it).
- Manual provisioning — This is needed when you intend to build your app from a build server. Unlike automatic provisioning (where your Visual Studio environment just fetches what it needs from the paired Mac), you instead enter the necessary signing identity and provisioning profile information into Visual Studio.

So if you are setting up your iOS app to be built on a build server such as Azure DevOps, you will to use manual provisioning.

When setting up an iOS build you firstly need to select the correct agent pool from Azure DevOps. In this case select the Hosted macOS agent pool. Selecting this provides you with a template consisting of the core tasks necessary for building your iOS app.

- Install an Apple certificate
- Install an Apple provisioning profile
- Build Xamarin.iOS solution
- Copy files to the artifacts staging directory
- Publish the build artifacts

We are also using Visual Studio App Center so I have the following task defined too.

- Deploy to Visual Studio App Center

We intend to use App Center for testing but we haven’t set this up just yet.

Installing the Apple certificate and provisioning profile
=========================================================
The Apple certificate and provisioning profile can both be downloaded from your Apple developer account and uploaded to your Azure DevOps build pipeline. The certificate should be in the form of a .p12 file which differs from the .cer file. You may need to open the certificate in XCode on a Mac to generate the required .p12 file. Either way, once you have these files, they need to be uploaded to Azure DevOps. Your build will fail without them.

Build the Xamarin.iOS solution
==============================
Before you proceed to this step, ensure you have set your Xamarin.Forms iOS project to use Manual Provisioning, and set values for the Signing Identity and Provisioning Profile (and these match the previously uploaded certificate and provisioning profile from earlier).On the build task check the box Create app package if you want to create an .ipa file (which is the file that is actually installed onto the devices). If you intend to test your app in any way, then presumably this needs to be checked.

The output from this task should be the required .ipa file.

Copy files to the artifacts staging directory
=============================================
The template makes a good job of this, so this task should need very little configuration. Basically, all the task is doing is copying the generated .ipa file from the build folder to the artifacts folder from where it can be used by subsequent build tasks.

- Source folder — $(system.defaultworkingdirectory)
- Contents — **/*.ipa
- Target folder — $(build.artifactstagingdirectory)

Publish the build artifacts
===========================
This task simply publishes the contents of the artifacts folder from above — $(build.artifactstagingdirectory)

At this point we now have a complete build process that has generated an .ipa file using the latest code changes, and published that .ipa file so that it is available for subsequent build processes such as testing and / or deployment. So at this point you can use your preferred testing / deployment tools of choice. In my case, I have deployed the generated .ipa file to App Center for testing and deployment.

Deploy to Visual Studio App Center
==================================
You will need to configure your build with an App Center token. This authorises your build process to access App Center studio on your behalf. I will write a future article on App Center, but for now it is sufficient to know that I have two apps configured in App Center — one for iOS and one for Android. Once configured, enter the name of the App Center connection into your Azure DevOps task.

If you are using App Center as part of a team then it’s a good idea to create an organisation, and assign your developers to the organisation. Then in the App slug you would enter {organisation-name}/{app-name} e.g. myOrganisation/MyAppName.

Now for each build that is triggered, we have a full build pipeline that builds the iOS app and deploys it to App Center from where we can deploy it to actual physical devices (allowing us to monotor analytics, crashes and push notifications).

Setting up this build process has been far from straight-forward. I encountered several problems along the way, and didn’t always find answers to my questions. Many times it was down to good old fashioned trial and error, along with a dash of perseverance.

A father, cyclist, vegetarian, atheist, geek and multiple award winning technical author. Loves real ale, fine wine and good music. All round decent chap.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store