Lessons Learned at Q5id

     

Xamarin

I spent a little less than a year at Q5id. It was the shortest amount of time that I’ve spent with an employer. I specifically picked Q5id because the CEO already had accomplished two successful startup exits, Unicru, which was acquired by Kronos Inc. in 2006, and SureID, which was acquired by Sterling Talent in 2017. Despite this precaution, I ultimately found working for a startup full-time to be beyond my appetite for risk and moved back to employment with a larger, more established company.

In addition to learning more about myself, I picked up some new technical knowledge while at Q5id, particularly around Xamarin. Xamarin is a cross-platform mobile application framework based on the C# and .xaml languages. In Xamarin all project styles are declared in the FormsApp.xaml. Unlike Android, styles can declared and set on a control basis by using the control’s xaml “Style={StaticResource yourFormsAppStyleHere}”.

At Q5id we used the MvvmCross NuGet to manage our architecture. NuGet is the package manager framework for .NET, similar to cocoapods in iOS or Gradle in Android. MvvmCross is a cross-platform MVVM framework for Xamarin Forms & Mono. It has both a MvxApplication and a MvxFormsApplication that you can extend. The former is used to register singletons with the MvvmCross IoCProvider to allow custom start functions for preloading network data when on the splash screen and to handle top level exceptions. The latter is used to handle application lifecycle event callbacks, such as OnStart(), OnSleep(), OnResume(), and OnAppLinkRequestReceived(). You can access the Forms Application programmatically in the Droid or iOS projects by invoking `Xamarin.Forms.Application.Current`. Note that even though MvvmCross has a function called `ConstructAndRegisterSingleton`, the objects instantiated as a result are not singletons. This can be confirmed by logging the result of `GetHashCode()` on any function call within the singleton and observing it can change throughout the lifespan of the app.

You can bind Android and iOS 3rd-party dependencies into your Xamarin project. Doing so causes Visual Studio to automatically wrap the apis in C# interfaces. Occasionally you will need to handle issues where the automatic wrapping fails. To do so you have to occasionally exclude or overwrite methods, fields, or metadata by using the files in the Transforms directory.

When debugging you can output to the console in C# (with string interpolation) by using the following format: `Debug.WriteLine($“New date {0}”, args.NewDate.ToString());`. This can be used to evaluate expressions in a similar fashion to XCodes `po` statement, or Android Studio’s evaluate expression dialogue. This last tip was particularly useful for me as was learning the ropes for Xamarin.

To summarize, after nearly a year of working with Xamarin I found it to be particularly good for sharing code with between iOS and Android on simple CRUD (Create, READ, Update, Destroy) applications. I found that the more advanced your use case became however (AI, ML, Augmented Reality, IoT, wearables, etc.), the less well suited it was. Microsoft did their best to provide escape hatches for these use cases through custom native library bindings, but I found many of the more nuanced aspects of this process to be undocumented and only resolved through meticulous trial and error. It is for good reason that seasoned .NET developers call this the “dark art” of binding. Next month we’ll take an in-depth look at the Kotlin equivalent of Xamarin, Kotlin Multiplatform Mobile (KMM).

comments powered by Disqus