X Platform — Xamarin
Following on from my first post Write once, run everywhere, I will now examine Xamarin in greater detail.
“Share code everywhere”
Use the same language, APIs and data structures to share an average of 75% of app code across all mobile development platforms. Build user interfaces with Xamarin.Forms and share nearly 100%.
Xamarin sounds like the answer to our dreams. We can write once in C# and use it across the major mobile platforms. The platform is built on the open source mono framework, which provides a cross platform implementation of Microsoft’s .NET framework. The compiler will produce a native app for iOS, an integrated .NET application and runtime for Android, and the underlying shared C# code can be shared with Windows phone apps.
How does it work?
Although the apps are all written in C# the underlying implementation differs across each platform.
For iOS the C# is compiled ahead of time (AOT) to ARM assembly language, this means that the code is static and it is not possible to perform any code generation at runtime.
For Android the C# is compiled into IL and packaged with MonoVM + JIT’ing. The app runs along side the Android runtime (Java/ART) and interacts with the native types via JNI.
For Windows phone we use the shared C# libraries we created for the other platforms, it doesn’t require the Xamarin tools.
Platform SDK/API Access
The Xamarin framework exposes the UI toolkits for iOS and Android in the C# syntax. The new Android Support libraries and other native sdks & libraries are also available by downloading the required Xamarin component.
To build a Xamarin app you can use to use either Visual Studio (Windows only) or Xamarin Studio (Mac/ Windows).
While Xamarin Studio can be used on Windows I’d advise against it, it isn’t actively developed as much as the Mac version and the Visual Studio community edition is functionally better and free.
Xamarin Studio for Mac OS X. It works. But, I guarantee you will prefer your old tool (Android Studio/ Xcode) as it lacks the advanced smart code completion and UI editing features we are used to.
Here’s one guys experience with Xamarin Studio.
- It works. You can build fully native apps and that look just like a native app. The platform’s APIs are also fully accessible when creating platform specific features
- 50% — 70% Shared code is achievable. It forces the business, UI logic separation.
- C# language — is a modern, full featured, object oriented language. Java lacks in comparison, especially when Android only allows us to use Java 7 Language features.
- Developers not restricted — they can switch between platforms, no need to learn new language, or switch between dev tools. A pure C# developer can work on the core library without deep knowledge of the underlying platform. If your backend is also C# those developers can be shared too.
- Extra moving part — Another layer in the toolchain adds complexity and another set of framework specific bugs that must be contended with. Testing will become more time consuming and complex, probably why they provide a Xamarin Test Cloud solution.
- Cost savings are debatable. You need developers with specific platform knowledge in Android, iOS, and Windows phone, as well as how to use the Xamarin framework and write in C#. The developers will not exclusively be developing in C# they still require knowledge of Java and Objective-C to develop platform specific functionality like video playback.
- Licensing — To use Xamarin in a company you need to purchase an annual $999 license, per developer, per platform
- Community — The community is smaller than the iOS and Android communities. Which means it is less likely someone has already had a similar issue. However if you are paying for licencing you should get some direct support.
- Lack of open source libraries — The number of high quality open source C# libraries built with Xamarin in mind lags behind the iOS and Android counterparts. Most likely a result of a smaller community.
- Trapped — Once the app has been developed it is very difficult to get out of the Ecosystem. The existing codebase cannot be used the whole app will have to be re-developed.
- Performance profiling (iOS) — Apple instruments one of the most helpful iOS development tool — is near entirely useless because the .NET Runtime is blackboxed for this application. Only less important attributes can be monitored. This circumstance withdraws an important optimisation and analysis tool from the developers.
- Performance profiling (Android) — Xamarin profiler (in Beta) allows profiling of the MonoVM, however thats only half of the picture as we need to look at the Android runtime’s JavaVM. Also if we reference native code we need to look at the memory used there too. We have a lot more places to look for large memory allocations and leaks making optimising your app harder and time consuming.
- Limitations — The iOS and Android platform both have some limitations. However these limitations do not prevent us from creating Xamarin apps.
Cross skilled developers. With the introduction of Swift there is no reason Android developers can’t easily learn Swift or vice versa. By encouraging cross platform skillet we are more likely to have similar implementations on each platform, thus reducing platform specific app bugs or differences.
What are you creating? Does the app have a lot of core logic that sits on the client or is it just a thin client that fetches and displays data?
Arguably the latter doesn’t need a CPT because all the business logic is in the backend and the bulk of the code is contained in the UI. With Xamarin your UI should be created for each platform (If you want a polished UI), so the code you are sharing will be limited to the model, & network layer.
For an app that contains vital business logic on the client, Xamarin makes sense. For example imagine a car tracking app for an insurance company, they want to collect information about their customer to determine how they drive. That logic is essential for determining the risk of insuring them and writing this core logic once makes sense. You can find & fix bugs once, and improve core logic once.
Existing developers and teams. Another consideration is the developers and teams already in a company, as well as the apps that already exist in a company.
Do we already have native developers? or do we mostly have .NET developers? We should do what makes sense to meet the goals of the company with the people we have. If we have native developers and want a great app within a short time, go native. If we have a lot of .NET developers with a few native and want to deliver quickly then, it may make sense to use Xamarin.
Do we have apps that we support in the company? If we already have apps in a company, we can share code per platform rather than across platforms. Debatably this has a similar time /cost saving effect. It will allow the developers to work on the cool and exciting features that user wants rather than implementing “sign-in” in 5 different apps.
Android Memory and Performance (Updated)
Xamarin.Android apps run within the MonoVM, the execution runs side-by-side with the Android Runtime. Which means creating a low memory, high performance app becomes more complex. (#perfMatters and all that).
Before making a Xamarin app it is important to under stand how garbage collection works with the two virtual machines. Specifically this important fact about peer instances (references to Java objects from Mono):
The GC has an incomplete view of the process and may not run when memory is low because the GC doesn’t know that memory is low
For example, an instance of a Java.Lang.Object type or derived type is at least 20 bytes in size (subject to change without notice, etc., etc.). Managed Callable Wrappers do not add additional instance members, so when you have a Android.Graphics.Bitmap instance that refers to a 10MB blob of memory, Xamarin.Android’s GC won’t know that — the GC will see a 20-byte object and will be unable to determine that it’s linked to Android runtime-allocated objects that’s keeping 10MB of memory alive.
I’m not saying that Xamarin runs slower than native apps, according to this post it can actually run faster. I am just pointing out that optimising memory usage can become more complex, due to the extra MonoVM.