A never-ending and often emotional debate in mobile development circles remains whether to use a deep cross-platform tool such as Xamarin, or develop apps natively? It’s almost impossible to find impartial analysis as nearly every reviewer comes in with an underlying bias. At WillowTree, however, we use both approaches, and in the end it all depends on the project and your organization. Here are some things to think about when we tackle this all-important platform problem for a client:
Upsides of Xamarin
C#: One of the major upsides of using Xamarin is the ability to use C# as your development language on all platforms. While both Objective-C and Java are great languages, C# has evolved considerably over the years. It allows for incredibly rapid development and iteration with strong type safety. Newer patterns in C#, including generics, LINQ, implicit typing, extension methods, async methods, and closures make what would be incredibly long boilerplate code in other languages completely unnecessary, which helps create cleaner, more readable and more reliable code.
Shared Core Code: While we have had some portability issues (they’ll be mentioned later), sharing code between Android and iOS is fairly clean and simple, thanks in part to constraints imposed on us by MVVMCross. Our models, view models, networking and parsing logic (including error handling), and navigation logic are often shared between both versions of the app. This means there are no differences in functionality between the two, simplifying bug hunting and ensuring similar operation between both apps. Of all bugs reported in Xamarin apps, a very small number are usually platform-specific, meaning fixes can be applied to both platforms easily.
.NET (and other C#) Libraries: .NET has some great libraries (including HTTPClient), and with the increased support of PCLS and Microsoft’s recent re-licensing of some of its libraries, using these libraries makes doing certain complex tasks on the platform incredibly easy.
** Native APIs:** Xamarin’s bindings on any given platform mirror the native calls so closely that if you know the API, you can easily find its equivalent Xamarin, with very few exceptions. Xamarin’s only conversion is making certain native calls conform to C# conventions and features (like properties, events and delegates). This not only makes transitioning easier for developers that are used to native development, but also means that you can refer to native documentation to learn how something works, and then easily transition it into C#.
MVVMCross Binding: Bindings using MVVM Cross can make a lot of boilerplate code for binding properties to visual components just disappear. This is especially true for Android views, where bindings can be added directly to the XML layout files.
Concerns with Xamarin
C#: While I love using C#, I have to admit that it has a lot of its own quirks, and it adds a lot of its own boilerplate (at least over Objective-C). This includes defining property methods for any property that needs to be observable and special boilerplate for events. Some of these can make code more verbose, and harder to read if you’re not used to it.
MVVM Cross Magic: MVVM Cross is a great framework for when you want to do cross-platform development, since it requires a hard separation between Model, Model View and View. However, in a lot of cases, MVVM Cross does some “magical” binding work that isn’t easy to follow, and frequently doesn’t perform the operation you expect. Initialization of new Model Views, for example, requires that the initialization parameters be serializable, and does not work well with overloaded Init methods. This pattern makes these calls more cross-platform, but can be incredibly confusing.
Portability Woes: While most of the code in our core layers is typically portable, sometimes the structure of the View Model (VM) is created to cater to the View in one platform or another. An iOS or Android developer developing the VM would bias the structure of the data toward his/her platform’s views - and most developers out there, even Xamarin-only developers, have a bias towards iOS or Android. For more complicated apps, this becomes a real issue until more developers become accustomed to making concessions for all platforms involved.
Xamarin Implementation Errors: Though infrequent, we occasionally come across errors in the way Xamarin implements bindings to certain native libraries or functions. While there wasn’t anything we couldn’t work around, seeing these errors is always worrisome. All of these bugs are now in the Xamarin bug database and will hopefully be fixed in future versions.
3rd Party Libraries: On both iOS and Android, there are certain third-party libraries you get used to using, especially UI components that make life easier on your target platform. Unfortunately, using these libraries on Xamarin is non-trivial. Even though Xamarin offers bindings for some of the more popular libraries, some developers would need to provide bindings for themselves, and this is not as easy as Xamarin make it seem.
Non Portable .NET Libraries: If you decide to use a PCL core library, you will have problems finding 3rd party libraries that support it. Some companies that offer .NET libraries to interface with their APIs do not yet offer PCL versions, or do not have PCL versions that support Xamarin iOS or Xamarin Android. This is particularly true for Google APIs. While Google offers PCL versions of some of their APIs, they do not have versions targeting Xamarin platforms. This means you would have to rely on the native libraries, which have the drawbacks listed above, or Xamarin implementations. Thankfully, with the new Shared Projects systems in Xamarin Studio and Visual Studio, you do not have to use PCLs.
Xamarin Studio: Personally, I like Xamarin Studio. It’s a pretty good IDE. However, the most recent versions of Xamarin Studio can be pretty buggy. “Go To Definition,” for example, is completely broken when attempting to go to a definition in metadata. In addition, some of the niceties that developers get used to from other IDEs, such as full tab completion for Android layout files, and features included in the iOS Asset Bundle editor, are just missing in Xamarin Studio, which can make rapid development much more difficult.
Some things to think about
Not Native: Xamarin compiles C# to native code, but still relies on the Mono runtime to do a lot of its work. Although the C# is running natively, it still uses Mono’s implementations for certain primitives (including arrays and dictionaries), which may or may not be optimized for the target platform. Objects created in C# are also still garbage collected, which can be a problem if you’re not careful about and when you’re allocating memory (and when the GC might fire). Additionally, while iOS library calls are almost always P/Invoked directly to native code, calls into Android need to be marshaled out of C#, then back into Java to call the proper Android functions. All of these can have an impact on performance, but we typically don’t see them as significant unless the app is calculation intensive, so mileage may vary.
Xamarin Forms: WillowTree started working with Xamarin before Xamarin Forms was released, and for that reason we haven’t really experimented with it. However, we feel it’s definitely something to look into, especially if your designs tend to reuse similar controls components between platforms, or between projects. Used properly, there is the possibility that a well made Xamarin Forms library could save significant effort when creating commonly used views.
In the end, it all comes down to the project, and the developers who will support the code in the long-term. Some things that will impact your decision:
Organization: If you have a deep C# bench, or alternatively, large Objective-C, or Java teams, the decision may be obvious for you.
Business Logic vs. Presentation Layer: Xamarin really shines in apps with significant business logic (e.g. caching rules or deep if-then scenarios) and more standard designs. You will only be writing the complex business logic one time, which also has QA benefits. Conversely, if you have an app with highly developed presentation layers, and either little business logic or most of it done on the back-end, your gains from using Xamarin will be more limited as you’ll be doing much of the presentation layer twice anyway, so your most efficient path is to go native and take full advantage of the native toolsets and platforms.
In the end, Xamarin and native approaches will both get you there on most projects, but they each have unique advantages that need to be weighed carefully based on project constraints and organizations involved.