Xamarin

Under the hood of the Azure Mobile App

For last 6 months I’ve been working on the Azure Mobile App for iOS and Android. We officially announced it at Microsoft’s //build conference keynote last month.

Now, you can monitor your Azure Resources from your phone! You can also take quick management actions, like start/stop/restart. Actually, you can do whatever you want using Cloud Shell that enables you to execute any command available through Azure CLI and PowerShell.

To learn more about the app functionalities, check out Michael Flanakin‘s blog post: Introducing the Azure app public preview.

Xamarin

The app is built with Xamarin Native in C#. To learn more about Xamarin, checkout my blog post Getting started with Xamarin in 2016.

The great thing about Xamarin Native apps is the fact that you can do everything what is possible when building native iOS apps with swift and native Android apps with Java. You can take any code sample in swift or Java, translate it to C# and use in your Xamarin app. Additionally, you can share code across platforms. We have around 60-70% code share. Most of our code is shared using PCL (Portable Class Library). Some components are in Shared Project.

Azure Mobile Solution

Continuous Integration and Continuous Delivery with VSTS and Hockey App

VSTS provide awesome tools for customizing build params, running tests, and deploying with HockeyApp. What’s more, when you are publishing your alpha/beta builds with HockeyApp you get auto-update notifications for free.

We have 3 environments:

  • alpha – deployed on every commit if tests are passing (used by team members)
  • beta – deployed after merge from alpha branch if all tests are passing (available for all Microsoft employees – it allows us to test the next release candidate)
  • App Store / Google Play – deployed manually (Apple does not provide mechanism to auto-deploy and we are working on automating Google Play deploy from VSTS)

Build definitions

I blogged about setting up VSTS for Xamarin.iOS earlier this year. Configuring Android build is much easier. Our VSTS build pipelines for iOS and Android look like below.

VSTS Xamarin.iOS build definition

VSTS - Xamarin.Droid build definition

The general scenario is:

  • build in Debug mode (in order to initialize TestCloud, which I described in this blog post)
  • run tests
  • build in Release mode (without TestCloud init code)
  • deploy to HockeyApp

We are thinking about running tests in Release mode (it requires passing TEST_CLOUD build param to build command explicitly). This will give us the same app that later on will be deployed to HockeyApp. A few times we had situations when app was working fine in Debug mode and all UI tests were passing, but it was crashing on startup in Release mode. In this case, if somebody updated app on their device, they had to uninstall it, and install manually again after we fixed bug causing crash. Very inconvenient.

Storing secrets

VSTS provides mechanism to keep your secrets (passwords and tokens) outside of your source code. You can store them in Variables tab in your build definition. Notice small lock next to secret value. Once you click it, it will hide the secret forever. There is no way to read it back from VSTS. I’ve done this a few times, and had to regenerate keys and tokens. You can store your secrets in Azure KeyVault, where they are always readable.

VSTS - variables

When you are running UI tests, usually you need to authenticate (AKA you need password to login with your test account). There is no way to pass password as parameter to Test Cloud, but there is a workaround: we have file Password.txt in UI test project (without password of course), and before running UI tests, we run shell script that takes password (from VSTS Variables) as parameter and writes it to the Password.txt file. You can pass variables stored in VSTS as arguments to VSTS tasks.

This is shell script:

#!/bin/bash
echo $1 > $2/Tests/AzureMobile.UITests/password.txt

And this is VSTS task:

GetPasswordForTestCloud

VSTS is awesome! It allows you to do almost anything with VSTS tasks or custom scripts. You can modify version number in Info.plist file before building solution, add release notes from git commit messages and much, much more.

UI tests with Xamarin Test Cloud

TestCloud is awesome. It allows you not only automate UI testing. It also enables you to test your app on hundreds of devices without need of buying any of them.

UI tests are usually the longest running task in our build pipeline. In order to minimize wait times between builds, we run UI tests only on one, most reliable device. We have separate build definitions to run UI tests nightly on 20 iOS and 40 Android devices. It takes longer, but it helps us to identify issues related to particular device model. Most of the time we don’t have changes that are breaking single device.

We are also thinking about creating 1-2 smoke tests that will be run on every commit, and run entire suite nightly or on separate build (to don’t block other runs).

Don’t assert! Use WaitFor!

UI testing 101: when you are writing UI tests, remember to wait for UI to update before asserting some condition. E.g., let’s say you have button and label. After button click, you expect label to update its text to ‘Button clicked’. Below test will be very flakey:

  app.Tap("myButton");
  Assert.AreEqual("Button clicked", app.Query("myLabel").Label);

Label may not get updated before assertion gets executed. Instead you should use WaitFor:

  app.Tap("myButton");
  app.WaitFor(app.Query("myLabel").Label.Equals("Button clicked", StringComparison.InvariantCulture));

Page Object Pattern

Another very good practice for writing UI tests is to use Page Object Pattern. This allows you to isolate implementation details from tests scenarios.

Here is one of our tests:

[Test]
public void Favorites_AddToFavorites_ResourceVisibleOnFavoritesPage()
{
    // Arrange
    var resourceToFavorite = TestResources.Azurembwinvm;
    TapTabBarItem(Strings.Resources);

    // Act
    _resourcesPage.TapResourceByName(resourceToFavorite);
    _resourceDetailsPage.VerifyPresent();
    _resourceDetailsPage.ExecuteCommand(Strings.Favorite, Strings.Unfavorite);
    _resourceDetailsPage.GoBack();

    // Assert
    TapTabBarItem(Strings.Favorites);
    _favoritesPage.VerifyPresent();
    _favoritesPage.VerifyNavBarTitle(1);
    _favoritesPage.WaitForResourceByName(resourceToFavorite);
}

Here, are some methods implemented in Page class:

public FavoritesPage WaitForResourceByName(string resourceName)
{
    _app.Screenshot($"Waiting for resource {resourceName}...");

    _app.WaitForElement(resourceName);

    return this;
}

public FavoritesPage TapResourceByName(string resourceName)
{
    _app.Screenshot($"Tapping resource '{resourceName}'...");

    _app.WaitForAndTapOnElement(resourceName);

    return this;
}

public FavoritesPage WaitForNoResourceByName(string resourceName)
{
    _app.Screenshot($"Checking if resource '{resourceName}' is not present...");

    _app.WaitForNoElement(resourceName);

    return this;
}

Screenshots during UI tests

As you probably noticed in above code snippet, we are taking screenshots at almost every step. Thanks to Page Object Pattern we don’t have to think about it in our test steps, but only in our Page implementations. Screenshots helps a lot in diagnosing failures in TestCloud:

Xamarin TestCloud - screenshots

Above test is failing when Waiting for DetailsCommandLayout… Thanks to screenshot, you can easily identify the line of code responsible for failure.

Monitoring and Crash Reporting with HockeyApp and AppInsights

A lot of people are using HockeyApp for crash reporting. Not many people are using it for application logging though. That’s because HockeyApp does not provide a good way for searching logs. However, you can create an AppInsights bridge app and stream all HockeyApp events to AppInsights.

AppInsights provides very powerful query explorer to search through your logs.

By default logs are preserved for 3 months, but you can export them to storage account and keep forever if you want.

What’s more, you can create awesome PowerBI dashboards using data from AppInsights.

Xamarin Open Source plugins and libraries

We saved a lot of time by using cross-platform Xamarin plugins:

  • XamSettings Plugin (from James Montemagno) – it is an abstraction over native data storage (SharedPreferences for Android, NSUserDefaults for iOS) that allows you to store/access local data in shared code
  • FFImageLoading (from Daniel Luberda) – very powerful image library, it allows us to convert SVGs to native formats in runtime, in shared code
  • OxyPlot (recommended by Frank Kruger) – awesome, powerful, cross-platform chart library used for metrics visualization

Xamarin community is awesome. If you are building Xamarin apps, I strongly recommend you to join slack channel XamarinChat. You can find there a lot of great developers who are willing to help. We learned about FFImageLoading there. What’s more, Daniel Luberda (FFImageLoading top contributor) is very active there. One time, he fixed a bug in less than 6h after reporting it by us 🙂

Summary

I am really excited about this app. It is an awesome feeling to take an app from zero to //build keynote. I am even more excited because there is a lot more to come. You can help us with that! If you have an idea about what should be added/changed/removed in Azure App go to aka.ms/azureapp/feedback and add or vote for a feature.

In meantime, get the app from App Store or Google Play, and let us know what you think!

Check out me and James Montemagno chatting about the app on Xamarin Show:

*This post was written in the clouds during my flight from Seattle to Frankfurt 🙂


[HockeyApp + VSTS] Generate release notes from last git commit message

Continuous Integration and Continuous delivery for Xamarin apps with VSTS and HockeyApp is awesome!

I blogged about setting up CI/CD pipeline with VSTS+HockeyApp a few weeks ago.

If you want to add release notes to HockeyApp release you have two options:

  1. Add release notes manually, by setting ‘Release Notes’ property, and update them before every build (AKA – option that sucks)
  2. Add path to release notes file, by setting ‘Release Notes (file)’ property, and update it before every git push (AKA – option that sucks less)
  3. Add path to release notes file, by setting ‘Release Notes (file)’ property, and generate release notes from last git commit message on every build (AKA – option that rocks)

Applying options 1 and 2 is easy.

To make option 3 happen you need to add script that will get last git commit message, and output it to the file that you specified in ‘Release Notes (file)’ property. This script should be executed before ‘Deploy to HockeyApp’ step (of course).

For Xamarin.iOS you need to add ‘Shell Script’ task that can look like this:

echo "last commit: $BUILD_SOURCEVERSIONMESSAGE" > commit.txt

*it will output file to the same directory where shell script is located

For Xamarin.Droid and Windows builds, you can create PowerShell script.


Continuous Integration and Continuous Delivery for Xamarin.iOS with VSTS (Vistul Studio Team Services)

Visual Studio Team Services has great Continuous Integration and Continues Delivery support for Xamarin.

Recently I was configuring pipeline that would build the project, run unit tests (with xUnit), run UI tests (with Xamarin Test Cloud), and, if all tests pass, deploy new version of the app to Hockey App. During the process of creating VSTS build definition I encountered a few problems that I think are worth to share with you.

To make a basic build definition with building Xamarin.iOS project and deploying to Hockey App with VSTS+Xamarin check James Montemagno’s Continuous Integration for iOS Apps with Visual Studio Team Services first.

The issues I had, that were not described anywhere online:

  • I couldn’t use “Visual Studio Test” task for running xUnit tests, because every build definition on VSTS can be executed by only one build agent, and to build Xamarin project I needed Mac build agent.
  • How to run UI tests (with Xamarin Test Cloud) using the same build that would be later on deployed to Hockey App? Test Cloud requires init code that later on shouldn’t be present in deployed app.

Running xUnit tests with Mac build agent

This requires adding 2 tasks to build definition:

  1. Command Line task – to run tests with mono and xUnit console runner.
  2. Publish Test Results task – to display results in build summary

First, install xUnit console runner NuGet package.

To run tests, add command line task with following settings:

  • Tool: mono
  • Arguments: packages/xunit.runner.console.2.1.0/tools/xunit.console.exe YourApp.UnitTests/bin/Debug/YourApp.UnitTests.dll -xml UnitTestsResults.xml

Remember to replace YourApp with your app name, and set the same xUnit runner version that you have installed.

To publish test results, add “Publish Test Results” task with the following settings:

  • Test Result Format: XUnit
  • Test Result Files: **/UnitTestsResults.xml
  • Always run: true

Running Xamarin UI tests with Test Cloud before deploying to HockeyApp

The solution there is rather simple: build in Debug mode that has TEST_CLOUD preprocessor directive defined, run tests, and then build again in Release mode before deploying to Hockey App.

Delete files before build

For a while I couldn’t figure out why my tests are not passing when run from VSTS while they pass on my machine. It turned out, VSTS was using old builds for tests. I am not sure about MacInCloud, but if you are using your own Build Agent running on your Mac the directories that contains binary files are not being cleaned up before next build automatically. To avoid using old builds, you can add, at the beginning of your pipeline, “Delete Files” task and delete everything from bin/* and obj/*.

Summary

The final build definition looks like that:

Azure Status VSTS build definition

Let me know if I missed some details! I would be happy to add them! Also – if you know better way of doing that – let me know as well!


Getting started with Xamarin in 2016

Xamarin

Xamarin is a cross-platform mobile development framework that allows you to build native mobile applications with C# and share code between them. There are two approaches:

  • native Xamarin – write native UI code in C# (views cannot be shared, business logic can be shared)
  • Xamarin.Forms – write shared UI in XAML (native controls are being generated, and business logic can be shared as well)

Xamarin vs Xamarin.Forms

The beauty of the first approach is ability to take advantage of Swift (iOS) or Java (Android) code samples, documentation, and community support. Swift/Java code can be easily translated into C#. In Xamarin.iOS app you have storyboards, ViewControllers and everything else you know from native iOS development. Similarly in Xamarin.Android – there are activities, fragments, action bars etc.

Xamarin.Forms on the other hand allows you to build apps faster. It’s very good fit for business applications.

Which approach should you choose? Ask StackOverflow.

Resources to get started

The great way to get started with Xamarin is Xamarin University. You can also find variety of Xamarin courses at Pluralsight. I especially recommend Building Your First Xamarin.iOS App from Start to StoreBuilding Your First Xamarin.Android App from Start to Store, and Introduction to Xamarin.Forms.

Friend of mine, James Montemagno (Developer Evangelist at Xamarin), runs video series Motz Codes Live where he explores different areas of Xamarin: from internals of MVVM, through Xamarin Inspector, to using Azure as backend for Xamarin mobile apps. You can also find a bunch of his videos from variety of conferences on youtube.

Additionally, there is a bunch of guides, recipes, and samples at Xamarin website. The official documentation is also a good source of knowledge.

Many of you were asking about Xamarin.Forms on reddit. A lot has been changed in this area as well. Check out the latest, greatest Xamarin.Forms update from James on .NET Rocks:

Code sharing strategies

One of the main advantages of Xamarin is code sharing. There are two ways to share code across platforms:

  • Portable Class Library (PCL) – produces separated .dll
  • Shared Project – compiled into one assembly with platform specific projects (you can think about files in shared projects as they all are present in all platform specific projects)

Most important differences:

  • PCL can have referenced libraries, while shared project cannot.
  • When we want to test shared code then in PCL case it is enough to reference PCL project only in the test project, while shared project requires additionally to add reference for all references that are being used by Shared Project.
  • You cannot have platform specific code in PCL, while shared project allows that using compiler directives.

You can learn more about code sharing here.

Two apps – two approaches

A few months ago I created two mobile apps with Xamarin, for 3 platforms (iOS, Android, UWP) and published them to 3 stores (App Store, Google Play, Windows Store):

  • Shopping Pad – smart shopping list that allows you not only to create a shopping list, but also remembers items that you have purchased in the past, how often they have been purchased, and based on that suggests items for your next grocery store trip.
  • Bread Crumbs – enables you to save your current location, and you can navigate to it later on (useful if you are in the new city, and you want to comeback to some place that you are “currently at”)

In Shopping Pad I used Portable Class Library to share code between platforms. In Bread Crumbs – Shared Project. I used SQLite for persistence in both apps, and the only difference I experienced was in creating SQLite connections. In PCL you need to create connection on “platform project” (you cannot do it from PCL). Shared Project allows you to use conditional compilation, and instantiate connection(s) in one file (using compiler directives).

I created unit tests (with xUnit) for Shopping Pad, and I was able to test entire app logic (for 3 platforms!) with only one test project. No platform specific code. Awesome!

Many times when I was looking for a solution to particular problem, I was able to reuse native iOS (Objective-C/Swift) or Android (Java) code samples, and translate them into C#.

Even for these two, small apps, shared code reuse was significant during development process. Especially in keeping consistency across platforms.

Both apps are available on App Store, Google Play, and Windows Store (Shopping Pad, Bread Crumbs).

Tips & Tricks

The struggle you may (and you probably will) experience at the beginning is platform setup. I recommend you to use Visual Studio simulators for Android (with Hyper-V) – they are faster. You need to have XCode installed on your Mac in order to run iOS apps built with Xamarin.

I develop Xamarin apps with Visual Studio on my ThinkPad X1, and use Mac only as host for running iOS apps. Some people run Windows on Mac with Parallels. Others use Xamarin Studio for iOS and Android, and switch to Windows only for UWP development. This will minimize the number of configuration issues, but will also give you worse development experience. I find Visual Studio much nicer for C#, and also for Xamarin development.

Xamarin – Windows Setup guide and Xamarin – Mac OS X Setup guide can help you get through configuration process. There is also fresh post from James about Setting Up Xamarin on Surface Book.

During mobile apps development with Xamarin you will encounter some problems that will not occur when developing pure native apps with Swift and Java. To save you some time, here are the list of a few of typical problems, together with solutions:

  • Problem: connecting with iOS host sometimes will not work. Solution: update your Mac (and XCode), update Xamarin plugin for Visual Studio, make sure your XCode path in Visual Studio settings is correct, and restart both machines. If it does not help check other solutions here.
  • Problem: iOS simulators not visible in Visual Studio. Solution: link.
  • Problem: Error: “Failed to add reference to ‘System.Collections’. Please make sure that it is in the Global Assembly Cache.”. Solution: add, manually, Droid/iOS dlls to references.
  • Problem: free provisioning Xamarin.iOS app. Solution: this guide.
  • Generic solution for many problems: restart Visual Studio (seriously, I’ve seen many StackOverflow questions where somebody was wondering why something does not work, and then “oh…after restarting Visual Studio it started working”).

One, not Xamarin specific tip: if want to have relations in SQLite database? Use SQLite-Net Extensions.

Publishing apps to stores

Android – bananas! Seconds for auto-validation, and ~3 hours to the store. I didn’t encounter any problems except copyrights for Bread Crumbs app icon, which I had to change. It was automatically detected! Impressive! This guide is more than enough to guide you through the process.

iOS – ~20 minutes for auto-validation, and ~4(!) days to the store. You can check current wait times here. Creating app bundle might be a little bit challenging. I was able to figure it out with Xamarin guide and this gist (I recommend option 2).

Windows Store – ~3h for auto-validation, and ~1 day to the store. I had my apps rejected, despite the fact that they were working on Windows machine, and on Windows Phone Device (Lumia 920). There were 2 issues:

  1. Referencing incorrect SQLite assembly: “SQLite for Universal App Platform” instead of “SQLite for Universal Windows Platform”.
  2. I didn’t test apps with with .NET Native (Project properties > Build > Compile with .NET Native Tool Chain), and one app was crashing during verification process. After debugging with .NET Native I was able to repro, diagnose and fix the problem.

Summary

Xamarin is not only sunshine and rainbows. You will have problems you wouldn’t when developing native apps, but also – you do not have some problems you would have when developing native apps. Check discussion about pros and cons of using Xamarin at Hacker News: Some thoughts after (almost) a year of real Xamarin use.

Be aware that there are also other cross-platform mobile frameworks, e.g., Apache CordovaReact Native, or NativeScript .

Since this year, Xamarin is free for Students, OSS projects and small teams (up to 5 people). You can use Visual Studio (including free Visual Studio Community Edition) or free Xamarin Studio Community Edition. That means – now you can use Xamarin for FREE!

Happy development!

Let me know in comments if you have any questions about developing apps with Xamarin!