Xamarin: A Panacea for Cross-Platform Mobile Development?

10 December 2015

For years developers have locked horns in the long-running debate over the best approach to mobile development. In the early days this debate was dominated by web aficionados pushing modern web technologies such as HTML5 and JavaScript. A key argument for this approach was the implicit cross-platform support that building apps that ran within a native browser offered.

However, with hindsight HTML5 has not offered the performance or user experience that mobile app users have come to expect (as Facebook discovered). Over time other web based technologies like Apache Cordova and Sensa Touch have emerged, but the lingering doubts over performance and user experience remain. So what is the current best approach to developing cross-platform mobile apps? Here at Instil we have spent the past 12 months experimenting with the Xamarin platform.

Xamarin, the New Kid on the Block

Xamarin allows developers to write mobile apps for Android, iOS and Windows Phone using C#. To the uninitiated this may sound a little perverse, of the three aforementioned mobile operating systems only Windows Phone natively supports the C# language. So how does it work? Xamarin relies heavily on the Mono runtime – an open source implementation of Microsoft’s .Net Framework, which includes a Common Language Runtime for Unix/Linux based operations systems e.g. Android and iOS. In addition to the Mono runtime Xamarin also incorporates C# bindings to almost all of the native Android and iOS APIs (including UI libraries) – enabling developers to create applications that are effectively native in performance and user experience.

A Pessimistic View

As always with new technologies it’s appropriate to approach things with a healthy dose of pessimism. This was most definitely the case for our mobile team, many of whom are seasoned native mobile developers with a strong affinity to Java and Objective-C. What follows is a summary of the thoughts and experiences from our team on embracing Xamarin over the past year.

The Pros

1. Performance

A major barrier to the widespread adoption of cross-platform mobile development tools has been the perceived performance of the end product. In particular users of apps developed using tools such as Apache Cordova or Adobe Air often comment that they feel less responsive than their native counterparts.

So just how well does Xamarin perform? Despite a number of very positive online benchmarks[1][2] we remained apprehensive when first experimenting with the tool. In part this was down to some healthy pessimism about benchmarks; but for the most part we were cautious as the apps we build often solve performance critical tasks. The first app we developed using Xamarin was no exception, an app targetting both Android and iOS to be used for monitor security camera feeds. Somewhat to our surprise Xamarin has more than held up to the task, allowing us to stream and render up to 10 concurrent video streams on Android (4.4+) and iOS (8.0+). This more than surpassed our expectations of what we would have been able to achieve, even with a native app built using the standard platform languages. From a developer’s perspective there are two key reasons why we have been able to achieve near native performance with Xamarin:

Xamarin provides direct access to the native platform APIs via C# bindings. With direct access to these APIs we were able to write code that performed optimally on each platform. For example, in order to maximise video rendering performance we were able to utilise Xamarin’s bindings to both the Android and iOS hardware decoders.

When deployed onto devices Xamarin apps execute on top of the Mono runtime. Whilst it may sound inefficient for apps to execute within a runtime the Xamarin team have done an excellent job tweaking Mono to perform on both Android and iOS. It is also worth noting that Xamarin are now a key sponsor of the Mono project[3].

2. The C# Language

What three words pop into your head when you think of the C# programming language? Ask most developers and they’ll likely associate the language with writing desktop and server-side applications for Windows based operating systems, not mobile apps! However, we have grown to love the language and found it is surprisingly well suited to mobile development.

As mobile applications are inherently multi-threaded and asynchronous developers often find themselves implementing variations of the delegate or observer pattern. In programming languages that don’t have first class functions this typically involves creating individual classes to handle specific callbacks e.g. Android’s OnClickListener for handling taps on views. The end result is often copious amounts of classes and boiler plate code. Lambdas offer a solution to this problem by allowing developers to declare inline blocks of code that can in turn be passed around as first class objects in place of this boiler plate code. The presence of lambdas and delegates in the C# language make it a surprisingly effective language to use for mobile development. Contrast this to using Java 6 / 7 for native Android development (which lacks the lambda support added in Java 8 [4]) and it could easily be argued that C# offers a more expressive and enjoyable language for mobile development.

Take for example the common use-case of registering a click listener for an Android button. The following code sample shows a typical Java approach of declaring a listener using an anonymous inner class:

protected void onCreate(Bundle savedInstanceState) {
    Button btn = FindViewById<Button=(Resource.Id.btn);
    button.setOnClickListener(new OnClickListener(){
        public void onClick(final View view) {
            Toast.makeText(this, "Clicked!", Toast.LENGTH_SHORT).show();                
        }
    });
}

In contrast we can achieve the same outcome in a more concise and expressive manner using C# delegates and lambdas:

protected override void OnCreate(Bundle bundle) {
    Button btn = FindViewById<Button=(Resource.Id.btn);
    btn.Click += (sender, e) =>
        Toast.MakeText(Application.Context, "Clicked!", ToastLength.Short).Show();
}

But what about Objective-C? Those familiar with the language will be aware that it has offered support for lambdas (known as blocks in Objective-C) for a number of years now, so the feature gap here isn’t so pronounced. However, it could definitely be argued that the C# lambda syntax is much easier on the eyes![5]

As well as the rich feature set of the language C# also offers a mature set of open-source libraries and frameworks that can be incorporated into Xamarin apps. Due to our love of all things reactive (see React Conf) we were particularly keen to experiment with the Reactive Extensions library. Reactive Extensions adds support for Reactive Programming paradigm to the C# language, allowing complex asynchronous tasks to be modelled as event sequences which can be elegantly queried, combined and orchestrated. The great news is that Reactive Extensions works perfectly on Xamarin/Mono and is used throughout are application architecture to simplify complex asynchronous call flows e.g. retrying of HTTP requests.

3. Reduced Development Time and Cost

The reduced development time and cost is likely the key business reason for opting to select a cross-platform development tool. It is therefore no surprise that Xamarin offers time and therefore cost savings vs. developing a native app for multiple platforms. However, it is worth emphasising a number of points:

The amount of development time saved very much depends on the approach taken. Whilst Xamarin offers a cross-platform UI framework (Xamarin Forms) there is also the option of using the native UI frameworks. Apps that require very tailored UIs would likely still require a C# implementation that utilises the Xamarin bindings to the native UI frameworks. Depending on the approach taken development time savings could vary.

In addition to saving time on the initial development effort Xamarin can reduce ongoing development and maintenance costs. By using Xamarin we have found that a lot of our non-UI code e.g. the model aspect of MVC can be written once and re-used across all platforms. In addition we can then a single set of unit tests to this shared code to ensure quality is maintained build after build. The Cons

4. Cost

Depending on your use of the tool Xamarin varies from $300 (indie / personal license) to $1,899 (enterprise license) per annum – note that this is per developer AND per platform. There’s no questioning that Xamarin is pricier than its peers, many of which are free and open-source (e.g. PhoneGap). However, as developers we should be well aware that developing apps is by no means a cheap process and the cost of a license could easily be recouped in the effort and time saved in developing a single cross-platform application. Whilst it is therefore hard to argue with the value of the tool itself it is somewhat easier to question the value of some of the other tools in the Xamarin ecosystem. In particular Xamarin hosted device farm / test execution service (Xamarin Test Cloud) is billed at ~$4,500 per annum for business customers; significantly more expensive than Amazon’s AWS Device Farm and our current favourite BitBar’s TestDroid.

5. Availability of Open-Source Library Bindings

For Xamarin to consume native Java or Objective-C libraries it must do so via a bridge e.g. JNI on Android or PInvoke for Objective-C. Whilst the community has gone to significant effort to implement bindings for a lot of commonly used native open-source libraries there will always be some projects that have no or out of date bindings. The scale of the problem isn’t huge (so far we’ve only encountered one such library ECSlidingViewController for iOS), but it’s worth being aware of. It’s also entirely possible to generate and maintain your own bindings to libraries you wish to use and there are even tools for doing so e.g. Objective Sharpie.

6. Xamarin Forms

The holy grail of cross-platform frameworks is write once and run anywhere. Whilst this is great in theory many cross-platform frameworks fall short when it comes to creating a generic abstraction on top of each platforms native UI framework. Typically the abstraction doesn’t perform as well as the native UI framework or isn’t as rich in functionality or customisability. As Xamarin binds to the native APIs performance is not a problem here, the latter is however a problem. Like with all cross-platform UI abstractions the ability to polish and tweak your app’s UI is lost to the need to find a common set of capabilities across all platforms. As many of the applications that we develop here at Instil have very bespoke UIs we have yet to find a suitable project for Xamarin Forms, but it would seem pragmatic for a POC (Proof of Concept) or simplistic UI made up of lists or forms (hence the name).

Is Xamarin Right for you?

In the past it was easy to ignore cross-platform development frameworks due to their sub-optimal performance and un-native feel. However, in Xamarin we now have the ability to build native feeling apps with a single cross-platform code base. Of course, the value of this very much depends on your project, but for anyone considering developing an app for multiple platforms it is now hard to look past Xamarin.

References

  1. Mobile App Performance (By Harry Cheung)
  2. Mobile App Performance Redux (By Harry Cheung)
  3. http://www.mono-project.com
  4. Note Java 8 includes support for lambdas. The open-source RetroLambda project can also be used to add support for lambdas in older versions of Java (5-7).
  5. How Do I Declare A Block in Objective-C

Want to Learn More?

Here at Instil we have found real value in Xamarin and are keen to share our knowledge of the tool with the rest of the development community. If you are a C# or mobile developer keen to learn more about Xamarin we will be hosting a day-long workshop introducing the tool early next year. We intend to follow this up with some longer, more in depth training courses later in the year. If you would be interested in attending or would like more information then please get in touch.

Article By
blog author

Matt McComb

Principal Engineer