Last night I attended a great .NET Mobile Developer meet up at Microsoft’s NYC offices entitled “Hands-On: Building iOS and Android Apps with C#“. It was hosted by Greg Shackles, author of “Mobile Development using C#“. Greg also presented at Xamarin’s Evolve conference in Austin, TX this past April. At this meetup he conducted a hands-on demo on how to build a simple iOS and Android app using Xamarin Studio and C#.
Xamarin is the new company behind the Mono project. If you are a .NET developer, you may have heard a thing or two about Mono (Spanish for “monkey”). It’s an open source port of the .NET framework to non-Microsoft platforms, specifically Linux. It was started in 2004 by Miguel de Icaza, who wanted a better solution than Java for building cross-platform applications. Several years later the Mono team found a corporate sponsor in Novell, who was then acquired by Attachmate and later abandoned Mono. Sounds a lot like MySQL’s troubled history, no? Xamarin was formed out of the ashes of Mono, and they’re coming back stronger than ever.
In its early days Mono struggled to find an audience for its product. Few Linux developers wanted to use Microsoft’s .NET API, and Microsoft developers were just fine running their applications on Windows. With the advent of mobile, however, the company found a new breath of life: cross-platform app development. Mono was extended to run .NET on iOS and Android, which was no minor feat. Java, being the precursor to .NET and with its Dalvik virtual machine runtime, was decidedly the easier of the two. iOS, on the other hand, was much more difficult. The Xamarin team essentially had to write their own Ahead-of-Time (AOT) compiler to convert C# directly into ARM assembly code. Doing so, they avoided violating Apple’s rules against using a virtual runtime in iOS, as well as the overhead that goes with it. An iOS binary (.ipa) compiled using Xamarin is essentially indistinguishable from one using the LLVM compiler. The only difference is a 2.5MB difference in file size because of the additional Mono libraries.
In addition to the core compilers, Xamarin also has their own IDE called Xamarin Studio, the successor to MonoDevelop. It runs identically on Mac, Windows, and Linux. It’s no Visual Studio, but keeps getting better. Xamarin Studio includes an Android GUI design surface, and an alpha release supports native editing of iOS Storyboards (not XIB files…yet). To compile iOS apps, Xamarin Studio must be run on a Mac, or at least built using a build server on a networked Mac. This is also how Xamarin is able to support writing iOS apps in Visual Studio on Windows. For seasoned .NET developers who can’t live without it, Xamarin Studio does provide Resharper-like source code analysis (but it must be enabled in the preferences). One of Xamarin Studio’s killer features is the Component Store – a NuGet-like marketplace for libraries and user interface elements. Some are free, and some are paid. Some are also quite expensive! Another great feature is the MonoTouch.Dialog library, which gives developers a declarative syntax for creating tables in iOS. This has been so successful that it has been ported back to native iOS via the QuickDialog project! Objective Sharpie, still in beta, is a fantastic tool that allows Mono developers to generate .NET assemblies and use compiled Objective-C libraries in their Xamarin apps. Another killer feature, just announced at Evolve, is TestCloud. It lets developers automatically run integration tests on their apps on hundreds of devices, including performance statistics and screenshots. Unfortunately it’s not yet publicly available for testing.
Working with the iOS and Android API’s in C# has its own benefits and challenges. It is a beautiful thing to bring namespaces, static types, generics, event handling, and LINQ to iOS, but there are also problems. Developers still have to be aware of underlying platforms. For example, Objective-C protocols are very similar to C# interfaces, but the Xamarin team had to implement them as abstract classes instead because C# interfaces don’t support optional members. The trouble is that C# can only supports single inheritance, so the typical Objective-C pattern of classes implementing multiple protocols is broken. Some also argue that .NET’s static typing goes against the dynamic nature of the Objective-C runtime. Developers also need to be aware of ARC retain cycles when using delegates or lambdas, which they might not be familiar with coming from managed C#. There also used to be problems with LINQ statements and using generics with value types. Greg recommend writing lots of unit tests and always running them on the actual device. Every layer of abstraction like Xamarin has its issues. The question at hand is whether productivity can be improved without sacrificing technical performance.
So does it really work? Yes, but making cross-platform apps properly still takes a bit of work. Because of the unique nature of the iOS and Android interfaces, it is nearly impossible to use the same code for both without creating a very generic, unappealing, lowest-common-denominator interface. The solution is to centralize as much common business logic (workflows, database storage, network calls) in a common library and reference it from separate dedicated iOS and Android projects. The trick is to keep these “UI layers” as thin as possible and centralize as much code as possible. But sharing a common business logic library is a bit wonky. It’s not so simple as simply referencing the project from the UI projects. You need to create separate wrapper projects for both iOS and Android that link to the files in the library project, and then reference those from the UI projects. This creates problems every time you refactor the underlying source files in the library project. Clearly this is suboptimal at best. Apparently Xamarin is working on using Microsoft’s new Portable Class Library to create single DLL’s that can be easily shared across platforms. This is easier said than done. Xamarin does provide a library called Xamarin.Mobile that abstracts some of the core features of any mobile platform (storage, GPS, network). An even better solution is MvvmCross, a separate open-source framework that builds on top of Xamarin and provides additional UI resources, and advanced tools such as better unit testing and dependency injection.
The Xamarin team does a great job of staying up to date on .NET, Apple, and Android releases. They used to use .NET subset based on .NET Silverlight but now they use Mono 3.0 which is equal to .NET 4.5 (including the new async and await feature in C#). Perhaps the biggest impediment to using Xamarin is not technical but rather its stringent and expensive licensing. The useful version of their software costs $1,000 per developer per platform per year! That’s right, if for 3 developers developing for both iOS and Android it’s $6,000 per year! Xamarin also hurts users of its free software by severing limiting the size of of apps they can build and run in the simulator for free. Xamarin is clearly banking on big companies (especially finance), who are likely already heavily invested in .NET as its target market.
So how to decide whether to use Xamarin or go native when building an app? Here is some things to think about when answering that question:
- Does your team primarily know .NET and C#? Go with Xamarin.
- Do you want to develop faster and write less code? Go with Xamarin.
- Is your app extremely performance-intensive? Go native.
- Are you building your backend in .NET and wish to create an “offline” mode for your app? Go with Xamarin.
- Are you planning on going cross-platform and wish to reuse as much code as possible? Go with Xamarin.
- Are you on a tight software budget? Go native.
- Do you wish to learn the nuances of each language and platform so you can think and develop differently? Go native.
Personally, I decided to go native because I like to get my hands dirty. I like to learn to think in a new language and framework. Plus it makes me appreciate Xamarin’s time-saving features all the more. I’m just not sure Xamarin is right for my purposes at this point. How about you?