When we start a new project, we always ask ourselves if we should choose Xamarin over a full native solution. I wanted to reflect on past projects and see if it was really worth using Xamarin.
But how do you compare projects? I decided to use line counting. It can seem obvious or simplistic, but the number of shared lines of code will easily show how much work has been done once instead of twice. I took the two most recent Xamarin projects that we worked on Ticketcorner Ski and together.
I used the following method:
- Use the well-known cloc tool to count the number of lines in a project.
- Count only C# files.
- Other types such as json configuration files or API response mocks in unit tests do not matter.
- Make an exception with Android layout files.
- Our iOS layout is all done in Auto Layout code and we don't use Xcode Interface Builder.
- To have a fair comparison, I included the Android XML files in the line count.
- Do not count auto-generated files.
- Do not count blank lines and comments.
- Other tools like Fastlane are also shared, but are not taken into account here.
If you want to try with one of your one project, here are the commands I used for the C# files:
cloc --include-lang="C#" --not-match-f="(([Dd]esigner)|(AssemblyInfo))\.cs" .
For the Android XML layouts, I used:
cloc --include-lang="xml" --force-lang="xml",axml Together.Android/Resources/layout
Here is what I found:
We can see that on those projects, an average of one third of code can be shared. I was pretty impressed to see that for Ticketcorner Ski we have the same number of lines on the two platforms. I was also pleasantly surprised to see that the project almost shares 40% of its code.
In a mobile app, most of the unit tests target the business logic, which is exactly what is shared with Xamarin: business logic and their unit tests are only written once. Most libraries not directly related to business logic are also shared: REST client, Database client, etc...
The code that is not shared is mostly UI code, interaction, etc... But it is also platform specific code: how to access the camera, how to handle push notifications, how to securely store user credentials according to each platform's guidelines.
It would not be fair to conclude that doing those projects in native would have been 30% more expensive. The shared code has sometimes to take into account that it will be used on two different platforms, and it gets more generic than it would be if written twice.
So... how do you choose one or the other ?
My goal with this blogpost is not to start a flame war on whether Xamarin is good or bad. I have shown here that for those projects, it was the right choice to use Xamarin. I want to share a few things we think about when we have to make a decision. Note that we use Xamarin.iOS and Xamarin.Android, but don't use Xamarin.Forms.
- Does the application contain a lot of business logic, or is it more UI-based?
- With one Xamarin project we worked on in the past year, a specific (and complex) use-case was overlooked by the client and it resulted in paying users being pretty unhappy. We were very pleased to be able to fix the problem once, and write the related unit tests once too.
- As a counterexample, for the Zürich Zoo app, most of our job was writing UX/UI code. The business logic is solely doing GET requests to a backend.
- Do you plan to use external libraries/SDKs?
- Xamarin is pretty good at using .jar files on Android.
- Native libraries on iOS have to be processed manually and it can be tedious to do. It is also hard to use a library packaged with CocoaPods that depends on many other pods.
- For both platforms, We encountered closed-source tools that are not that easy to convert. As an example, we could use the Datatrans SDK, but not without some trial and error.
- There are however other Xamarin libraries that can replace what you are used to when developping on both platforms. We replace Picasso on Android and Kingfisher on iOS by FFImageLoading on Xamarin. This library has the same API methods on both platforms which makes it easy to use.
- Do you plan to use platform-specific features?
- Xamarin is able to provide access to every platform feature, and it works well. It is also known that they update the Xamarin SDKs as soon as new iOS/Android versions are announced.
- For Urban Connect however, the most important part of the app is using Bluetooth Low Energy to connect to bike locks. Even if Xamarin is able to do it too, it was the right decision to remove this extra layer and code everything natively.
- Tooling, state of the platform ecosystems:
- In the mobile world, things move really fast:
- Microsoft pushes really hard for developers to adopt Xamarin, for example with App Center, the new solution to build, test, release, and monitor apps. But Visual Studio for Mac is still really buggy and slow.
- Google added first-class support for Kotlin, has an awesome IDE and pushes mobile development with platforms like Firebase or Android Jetpack.
- Apple follows along, but still somehow fails to improve Xcode and its tooling in a meaningful manner.
- Choices made one day will certainly not be valid one year later.
- In the mobile world, things move really fast:
- Personal preferences:
- Inside Liip there are very divergent opinions about Xamarin. We always choose the right tool for the job. Having someone efficient and motivated about a tool is important too.
I hope I was able to share my view on why and how we use Xamarin here at Liip. I personally enjoy working both on Xamarin or native projects. Have a look at together and Ticketcorner Ski and tell us what you think!