Going cross-platform with Xamarin–The Windows Phone App
This blog post series is a documentation for a talk I give about cross-platform development with Xamarin. This series was co-authored by Johan Lindfors at Coderox. This post talks about the structure of the Windows Phone app we want to port to Android.
This series will provide a step-by-step instruction on how to port a small Windows Phone app to Android, using Xamarin and MvvmCross. This post will explain some basic concepts, what the app does and how the code is structured.
What is Xamarin?
Xamarin is a third-party tool that enables you to write apps for Android, iOS and OS/X in C# using .NET framework but doing the user interface natively with the designers for each platform. Xamarin then generates native executable code, so the apps are indistinguishable from real native apps. The core benefit of this approach is to have all non-UI related code in C#/.NET in shared in one place, to be able to reuse it on multiple platforms. Often we see that up to 80% of the code gets reused between platforms, opening up to huge cost-savings when doing cross-platform development work. Xamarin also integrates nicely into Visual Studio, giving you a very efficient and agile development environment.
What is MvvmCross?
MvvmCross is an open-source, cross-platform framework that implements the MVVM pattern on all the above mentioned platforms. It will also give you the ability to use data binding on all these platforms, which is a very effective way to use code written with the MVVM pattern.
What is MVVM?
MVVM is a pattern for writing user interface code. MVVM stands for Model – View – ViewModel and is a variation of the MVC (Model – View – Controller) pattern. The different parts is as follows:
- Model. Here is where you put all your entity classes and the services to provide you with operations on those. This code is not related to the UI at all and can be shared completely between platforms, par device specific stuff like position tracking etc. These implementations need to be implemented per client and we will look at how that is done in the most portable way.
- View. This layer contains all the views and the code needed to drive the user interaction. This is always done per platform and with Xamarin you use the designer etc. for the platform. We also program against the native framework, but wrapped in .NET framework wrapper classes so we can write this code in C# as well.
- ViewModel. This is the glue between the model and the views. For each view we should have a companion view model, and the view model should contain all the data for the view as properties. It should also contain all the commands the view needs to work with the data. The view model then makes calls down to the service layer and use the entities from the model. Data binding from the views is a very powerful construct that gives us a very responsive UI with almost no code at all, so this is used throughout the code.
How is the code structured?
Our phone app, which we ultimately want to port to Android, is a simple little app for tracking your running activities, like RunKeeper, Endomondo etc. It’s very simple but illustrates the basic concepts and provides a good base to illustrate how we port this. This is how the app looks like an action:
So, its basically a pivot with four views, current, total, lap and map. We have an app bar that has start, stop and lap buttons. On the lap page, there is a list of completed laps. That’s the app and we can run it in the emulator since we can fake a series of location updates with the excellent Windows Phone emulator.
As mentioned above, the code is written using the MVVM pattern, so we have the following folders in our project:
Here we have a class that holds a single data Point (in our case a location at a specific time) and an interface and stock implementation of metrics around a Collection of data Points (speed, distance etc.).
Here we have defined three interfaces and done three concrete implementations:
- Collection service (IDataPointCollectionService.cs, DataPointCollectionService.cs). This holds an internal collection of the data points collected. This is a singleton service, meaning that we only want one instance of this service running. Key implementation here is an event that is triggered when we get a new data point, driving updates to the user interface. This implementation is not platform specific and can be shared across platforms.
- Position service (IPositionService.cs, PositionService.cs). This service listen for location updates from the phone and sends them to the collection service. This is a platform specific service, and needs to be reimplemented for each platform.
- Periodic service (IPeriodicService.cs, PeriodicService.cs). This services fires an event every second, since we need to recalculate metrics regularly, even though we don’t get location updates. This is also a platform specific implementation.
Here we define the view models that drives the user interface. I have chosen to a MainViewModel that contains the view models for the different pivots current, total and lap. I have also written a base class for all view models (ViewModelBase) and a base class for all pivots (DataPointMetricsViewModel). All properties propagate changes so that the user interface gets updated automatically.
The rest of the project is pretty vanilla from the templates. MainPage.xaml has the user interface.
So this is the base we start from when we port this app to Android. Our first step is to extract all reusable code into a portable class library. Blog post is here.
Also, if you are interested at this you should attend TechDays at Kistmässan 18-20 November 2014. There will be a preconference day where I and some colleagues will spend an entire day talking about this subject. More info can be found here.