In many ways Mobile development is like Desktop development.
Both Mobile and Desktop applications run natively on the device and their user interface depends on the operating system they are running on.
However, there’s currently no operating system that runs both on desktop and mobile!
Therefore, the tools and frameworks used for application development are different. Additionally, because mobile applications don’t run natively on the same device as they are being developed, the development experience isn’t as smooth as with desktop applications.
Front-end Mobile Development in .NET
When talking about mobile development, one usually thinks of an application running on a mobile device. This is usually referred to as front-end development.
In the .NET ecosystem, Xamarin is the obvious choice when deciding on a framework to develop a mobile application in. Despite that, Unity or MonoGame might be a better fit in some scenarios.
Xamarin
Xamarin is the .NET implementation for mobile devices. It was developed by a company with the same name which was acquired by Microsoft in 2016. Although Xamarin was originally a paid product, it is available for free to all developers ever since the acquisition.
There are two approaches to developing user interfaces with Xamarin:
Approach 1# In the traditional Xamarin approach, you create a new project for a single platform (Android or iOS).
In this case, native technologies are used for creating the views (layouts in Android XML files for Android, and storyboards for iOS). For example, the following Android layout file could be used in a traditional Xamarin project or a native Android project without any changes:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android=http://schemas.android.com/apk/res/android
xmlns:app=http://schemas.android.com/apk/res-auto
xmlns:tools=http://schemas.android.com/tools
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_main">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Hello World!" />
</RelativeLayout>
The code for the views is still written in C# instead of Java, Kotlin, Objective C or Swift and uses .NET base class libraries. Thanks to the .NET binding libraries provided by the Xamarin platform, Native platform-specific APIs can also be invoked directly from C#.
Approach 2# When creating a new project for multiple platforms, Xamarin.Forms UI framework is used instead.
It’s somewhat similar to WPF and UWP in that it is XAML-based and works well with the MVVM pattern. (You can read more about WPF and UWP, and XAML in my tutorial from the previous issue of DotNetCurry Magazine – Developing desktop applications in .NET.) However, the control set is completely different because under the hood it’s just an abstraction layer on top of the traditional Xamarin approach. This means that individual controls are rendered differently on different platforms: each Xamarin.Forms control maps to a specific native control on each platform.
Here’s an example of a simple Xamarin.Forms-based UI layout:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns=http://xamarin.com/schemas/2014/forms
xmlns:x=http://schemas.microsoft.com/winfx/2009/xaml
xmlns:d=http://xamarin.com/schemas/2014/forms/design
xmlns:mc=http://schemas.openxmlformats.org/markup-compatibility/2006
mc:Ignorable="d"
x:Class="XamarinApp1.Views.MenuPage"
Title="Menu">
<StackLayout VerticalOptions="FillAndExpand">
<ListView x:Name="ListViewMenu"
HasUnevenRows="True">
<d:ListView.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Item 1</x:String>
<x:String>Item 2</x:String>
</x:Array>
</d:ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="10">
<Label Text="{Binding Title}"
d:Text="{Binding .}"
FontSize="20"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
Although Xamarin.Forms initially imposed many limitations on the interfaces which could be developed with them, they have improved a lot since then. They are already at version 4 and are probably used for development of most new Xamarin applications today. In addition to Android and iOS, they also provide full support for UWP (i.e. a single Xamarin application can run on Android, iOS and Windows). Along with the three fully supported platforms, three more are currently in preview: WPF, macOS and GTK# (a wrapper on top of the GTK cross-platform UI toolkit). Tizen .NET adds support for Tizen applications as well (Samsung’s operating system for various smart devices).
In cases when the Xamarin.Forms control set doesn’t suffice; the so-called native views can be used to complement them. This feature gives access to native UI controls of each individual platform. They can be declared alongside Xamarin.Forms controls in the same XAML file.
Of course, each native UI control will only be used in building the UI for the corresponding platform. Therefore, a different native control will usually be used in the same place for each platform supported by the application, as in the following example:
<StackLayout Margin="20">
<ios:UILabel Text="Hello World"
TextColor="{x:Static ios:UIColor.Red}"
View.HorizontalOptions="Start" />
<androidWidget:TextView Text="Hello World"
x:Arguments="{x:Static androidLocal:MainActivity.Instance}" />
<win:TextBlock Text="Hello World" />
</StackLayout>
On mobile devices, UI controls are not the only platform specific part of the application. Some APIs are also platform specific, mostly those for accessing different device sensors (such as geolocation, compass, accelerometer etc.) and platform specific functionalities (e.g. clipboard, application launcher, dialer etc.). The Xamarin.Essentials library can make their use simpler by providing its own unified API for them across all supported platforms. Here’s an example of code for retrieving current geolocation:
var request = new GeolocationRequest(GeolocationAccuracy.Medium);
var location = await Geolocation.GetLocationAsync(request);
All of this makes Xamarin a feature-complete framework for developing mobile applications for Android and iOS. In this field, it is the only choice for .NET developers who want to leverage their existing .NET and C# knowledge for mobile application development.
Xamarin.Forms support for other platforms might make the framework an appropriate choice when trying to target other devices with the same application (especially once all supported platforms come out of preview). However, there aren’t many applications which would make sense on such a wide variety of devices with the same codebase, and this could be one of the limiting factors.
To read more about Xamarin, check out some tutorials at www.dotnetcurry.com/tutorials/xamarin as well as at https://docs.microsoft.com/en-us/xamarin/.
Unity and MonoGame
Unity and MonoGame are also based on .NET and can be used to develop applications which run on Android and iOS (but also on Windows, macOS and Linux, as well as most gaming consoles on the market today). In contrast to Xamarin which is meant for general-purpose application development, Unity and MonoGame primarily target (cross-platform) game development.
They take a different approach to enabling that:
- Unity is a 3D game engine with an easy-to-learn graphical editor. When developing a game, the editor is used for designing scenes which usually represent game levels, although they are also used for creating game menus, animations and other non-gameplay parts of a game.
Figure 1: Unity Editor main window
C#/.NET is only used for writing scripts which implement the logic to control the objects created through the editor, and bring the game to life. Here’s a typical example of a script in Unity:
public class PlayerDeath : Simulation.Event<PlayerDeath>
{
PlatformerModel model = Simulation.GetModel<PlatformerModel>();
public override void Execute()
{
var player = model.player;
if (player.health.IsAlive)
{
player.health.Die();
model.virtualCamera.m_Follow = null;
model.virtualCamera.m_LookAt = null;
player.controlEnabled = false;
if (player.audioSource && player.ouchAudio)
player.audioSource.PlayOneShot(player.ouchAudio);
player.animator.SetTrigger("hurt");
player.animator.SetBool("dead", true);
Simulation.Schedule<PlayerSpawn>(2);
}
}
}
- MonoGame is a much more low-level tool than Unity. It implements the API introduced by Microsoft XNA Framework – a .NET wrapper on top of DirectX which was discontinued in 2014.
It’s not a full-blown game engine, but it does provide a content pipeline for managing and processing the assets (sounds, images, models, etc.) used in the game. Still, developing a game in MonoGame mostly consists of writing .NET code responsible for managing the game state as well as doing the rendering. As you can see in the following example, MonoGame code is typically at a much lower level of abstraction than Unity code:
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(ballTexture, new Vector2(0, 0), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
Apart from games, Unity and MonoGame can also be used for developing other types of applications, especially when 3D visualization plays an important role in them. Good candidates are applications in the field of augmented reality (AR), industrial design and education. Unity is recently focusing on providing the tools to make development of such applications easier.
When deciding to develop an application this way instead of using general-purpose frameworks like Xamarin, it’s important to keep in mind the potential downsides of running a 3D engine inside your application. These considerations are even more important on a mobile device with limited processing power, connectivity, and battery life: higher battery usage, longer initial load time and larger application size. It is important that the benefits in a specific scenario outweigh them before deciding for such an approach.
Building and Running the Mobile Applications
Because mobile applications target a different device, they can’t be simply run on the computer where they are developed. They need to be deployed to an emulator or a physical device and run from over there.
For Android applications, this works on all desktop operating systems. Both Visual Studio and Visual Studio for Mac will install all the necessary dependencies to make it work, if you choose so. The built-in user interface will allow you to manage the installed versions of Android SDK and configured virtual devices for the Android emulator. When starting an Android application from Visual Studio, you can select which emulated or physical device to use.
Figure 2: Android Device Manager in Visual Studio 2019
Because of Apple’s licensing restrictions, this is not possible for iOS applications. To build and deploy an iOS application, a computer running macOS is required. To make development on a Windows computer more convenient, Visual Studio can pair with a macOS computer which will be used to build the iOS application and to deploy it to a physical iOS device (which must also be connected to the macOS computer).
Figure 3: Pairing to Mac in Visual Studio 2019
The iOS Simulator can also run only on a macOS computer. To avoid any interaction with macOS desktop when developing on Windows, Xamarin comes with Remoted iOS Simulator for Windows. When Visual Studio is paired with a macOS computer, it can run the iOS application in the iOS Simulator on Mac and show its screen in the Remoted iOS Simulator window. This window can also be used to interact with the iOS application as if the simulator was running locally on the Windows computer.
Back-end Mobile Development in .NET
In most cases, the application running on the mobile device is only a part of the complete solution. The data shown and manipulated in the application must be retrieved from and stored to somewhere. Unless the application is a client for an existing public service, it will require a dedicated back-end service for this functionality.
ASP.NET Core and ASP.NET Web API
The back-end service will typically expose a REST endpoint for the mobile application to communicate with. As explained in more detail in my previous DotNetCurry article Developing Web Applications in .NET (Different Approaches and Current State), these can be developed using ASP.NET Core or ASP.NET Web API. From the viewpoint of the back-end service, a mobile application is no different from a web SPA (single-page application).
This approach makes most sense when the mobile application is developed as a companion or an alternative to a web application with a similar functionality because the same back-end service can be used for both. It’s also appropriate when the back-end is not just a simple data-access service but needs to implement more complex business logic. The higher overhead of a dedicated web application gives full freedom to what can be implemented inside it.
Mobile Apps in Azure App Service
A standalone web application as the back-end might be an overkill if the mobile application only needs some standard functionality such as authentication, cloud storage for user settings and other data, usage analytics and similar. The Mobile Apps flavor of Azure App Service might be a good alternative in such cases.
It provides the following key functionalities implemented in dedicated server and client SDKs:
- Data access to any data source with an Entity Framework data provider (Azure or on-premise SQL Server, Azure Table Storage, MongoDB, Cosmos DB, etc.) with support for offline data synchronization.
- User authentication and authorization using social identity providers (Microsoft, Facebook, Google or Twitter) for consumer applications or Active Directory for enterprise applications.
- Push notifications using Azure Notification Hubs.
The .NET Server SDK consists of a collection of Microsoft.Azure.Mobile.Server.* NuGet packages which must be installed into an empty ASP.NET Web Application project for .NET Framework. The Microsoft.Azure.Mobile.Server.Quickstart NuGet package can be used for a basic setup with all supported functionalities, but there are also separate NuGet packages available for each functionality. The SDK needs to be initialized in an OWIN startup class:
[assembly: OwinStartup(typeof(MobileAppServer.Startup))]
namespace MobileAppServer
{
public class Startup
{
// in OWIN startup class
public void Configuration(IAppBuilder app)
{
HttpConfiguration config = new HttpConfiguration();
new MobileAppConfiguration()
.UseDefaultConfiguration()
.ApplyTo(config);
app.UseWebApi(config);
}
}
}
Individual functionalities can now be added with minimum code:
- For data access, an Entity Framework DbContext class must be created first with DbSet<T> instances for every table to be exposed. Then, for each table, a TableController<T> can be created using the scaffolding wizard for creating a new Azure Mobile Apps Table Controller:
Figure 4: Scaffolding wizard for a new Azure Mobile Apps Table Controller
- For authorization, the controller classes and action methods only need to be decorated using the standard Authorize attribute.
- For push notifications, the code sending them needs to instantiate the NotificationHubClient class and use its methods to send notifications.
- Additional custom API controllers can be exposed to the mobile application by decorating them with the MobileAppControllerAttribute class.
All of this is explained in more details in the .NET SDK Server documentation.
There’s a corresponding Client SDK available for several different technology stacks. Xamarin applications can use the .NET Client SDK by installing the Microsoft.Azure.Mobile.Client NuGet package. All calls to the Mobile Apps backend are available as methods of the MobileServiceClient class:
- To access data, the GetTable<T> and GetSyncTable<T> methods are available. The latter implements offline synchronization but requires some additional setup before it can be used:
- The Microsoft.Azure.Mobile.Client.SQLiteStore NuGet package must be installed.
- An instance of the MobileServiceSQLiteStore class must be provided to the MobileServiceClient instance:
var localStore = new MobileServiceSQLiteStore(localDbPath);
localStore.DefineTable<TodoItem>();
mobileServiceClient.SyncContext.InitializeAsync(localStore);
- Authentication can be done using the LoginAsync method.
- To register an application for push notifications, additional platform specific setup is required using the dedicated Google and Apple services. Only the corresponding device token is sent to the backend using the RegisterAsync method on the platform specific object returned by the call to the MobileServiceClient’s GetPush method. Handling of received push notifications is done using the standard API’s on each platform.
Microsoft has stopped further development of Azure Mobile Apps SDKs in favor of its Visual Studio App Center solution for mobile application development. However, for most of the functionalities described above, Visual Studio App Center doesn’t yet provide a functionally equivalent alternative which still makes Azure Mobile Apps the only choice if you need any of its unique features. This will very likely change as Visual Studio App Center is further developed.
Visual Studio App Center
Visual Studio App Center is a web portal solution with a primary focus on DevOps for mobile applications as provided by three core services:
- Build can connect to a Git repository in Azure DevOps, GitHub, Bitbucket or GitLab and build an Android or iOS mobile application developed in one of the supported technology stacks (Xamarin and Unity are among them, of course).
- Test can run automated UI tests for mobile applications directly on hardware devices, not on emulators. A selection of several hundred devices is available to choose from. Multiple test frameworks are supported as well: Xamarin.UITest and Appium on both platforms, Espresso on Android and XCUITest on iOS. The service is the successor of Xamarin Test Cloud.
- Distribute is responsible for application deployment. In addition to the official public Google Play and App Store services, Microsoft’s Intune mobile device management solution is supported as well. The latter can be used for deploying internal applications in corporate environments.
All of these can be controlled and tracked from the web portal.
The next important part of Visual Studio App Center are Diagnostics and Analytics services. To take advantage of them, the App Center’s SDK must be added to the mobile application. For Xamarin applications, the Microsoft.AppCenter.Analytics and Microsoft.AppCenter.Crashes NuGet packages need to be installed.
To initialize basic functionality, a single call to AppCenter.Start during application startup is enough. Additional methods are available for tracking custom events in applications and for reporting errors which were handled in code and didn’t cause the application to crash.
The web portal provides the tools to monitor and analyze all the analytical and diagnostical data submitted from the application. These can be used to track application stability, resolve reported crashes or errors, and explore application usage patterns to improve user experience and retention.
The remaining services to some extent overlap with Azure Mobile Apps:
- Data caters to application’s data access needs both in online and offline scenario. However, unlike data access features in Azure Mobile Apps it doesn’t build on top of Entity Framework data providers to provide this functionality. Instead, it relies on the features of Azure Cosmos DB database service which is the only supported data source.
- Auth provides user authentication by integrating Azure Active Directory B2C identity management service. In comparison to user authentication in Azure Mobile Apps it supports more social identity providers but can’t be used in conjunction with a corporate Active Directory.
- Push provides direct integration with Android and iOS native notification services (Firebase Cloud Messaging and Apple Push Notifications, respectively) and doesn’t use the Azure Notification Hubs service to achieve that like Azure Mobile Apps does.
Like Diagnostics and Analytics services, these three services also have corresponding Client SDK packages which make them easier to use. For Xamarin applications, these are the Microsoft.AppCenter.* NuGet packages.
It will depend on your application requirements which data access, authentication and push notification services will suit you better (the ones from Azure Mobile Apps or the ones from Visual Studio App Center). If you can achieve your goals with either, then out of the two, Visual Studio App Center currently seems a better choice for two reasons:
- There are additional DevOps services in Visual Studio App Center that are not available in Azure Mobile Apps. If you decide to take advantage of these, then using Visual Studio App Center also for services that have alternatives in Azure Mobile Apps, will allow you to manage everything from a single location – the Visual Studio App Center web portal.
- Unlike Azure Mobile Apps, Visual Studio App Center is still being actively developed which makes it a safer choice for the future. Currently, Azure Mobile Apps are still fully supported but it’s impossible to say whether or when this will change.
One can also safely assume that Visual Studio App Center will only improve with time. Existing services will get additional features and new services might be added.
Conclusion
For front-end application development, most .NET developers will choose Xamarin as the only general-purpose application framework. Unity and MonoGame are a great alternative for game development and can sometimes make sense for development of other applications with a lot of 3D visualization, e.g. in the field of augmented reality.
For back-end development, the best choice is not as obvious. Visual Studio App Center is the most feature complete offering and Microsoft continues to heavily invest in it. This makes it a good choice for most new applications. Azure Mobile Apps offers only a subset of its functionalities but can sometimes still be a better fit because it takes a different approach to them. Unfortunately, it's not actively developed anymore which makes it a riskier choice.
ASP.NET Core and ASP.NET Web API can be a viable alternative to the cloud services if you already have your own custom back-end or just want to have more control over it.
This article was technically reviewed by Gerald Versluis.
This article has been editorially reviewed by Suprotim Agarwal.
C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.
We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).
Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.
Click here to Explore the Table of Contents or Download Sample Chapters!
Was this article worth reading? Share it with fellow developers too. Thanks!
Damir Arh has many years of experience with software development and maintenance; from complex enterprise software projects to modern consumer-oriented mobile applications. Although he has worked with a wide spectrum of different languages, his favorite language remains C#. In his drive towards better development processes, he is a proponent of Test-driven development, Continuous Integration, and Continuous Deployment. He shares his knowledge by speaking at local user groups and conferences, blogging, and writing articles. He is an awarded Microsoft MVP for .NET since 2012.