How to Develop Portable Applications (iPhone and Android)

Mark Zachmann
Mar 23 · 5 min read

This is about Xamarin/C# but let me begin by describing why.

Intro

I just spent about 3 months writing a native (Java) Android application and then started on the iPhone/iOS version. After spending about a month going through samples and learning Swift (the native language for iOS) all I could think was “who the #$@% wants to write anything in Swift”? Just what we need is an entire language that is only supported by Apple.

It wouldn’t be so bad but they consistently ignore industry or common standards to go their own way. A line from Wikipedia -> “Swift supports closures (known as lambdas in other languages)”. If every other language calls it a lambda why call it a closure? Because you’re Apple I guess — but it’s murder on those of us who spend most of our time in embedded C++ or Python or in Windows.

After torturing myself for a while I decided to once again try Xamarin/C#. C# is the language of choice for Windows and Xamarin is Microsoft’s os-portable layer for using C# with Linux and iOS.

Showing all three implementations with a UWP (universal windows platform) code sample.

In the past I’ve tried Xamarin/C# and ended up using native languages. It was too buggy, missing too much functionality, or created way-too-slow an application. Not this time. Now that Xamarin is owned and supported by Microsoft (and open-source) it seems usable. I’ve written an entire Bluetooth application that has very little os-specific code and seems to work flawlessly in Android, iOS and Windows.

The downside to Xamarin/C# is application size and speed. There’s an entire porting layer in the middle (mono) and C# is a tokenized language. So, my Xamarin Android application is about 10MB and the native application with much the same functionality was 1.5MB.

Luckily phones and tablets are now plenty fast and lots of storage so 10MB vs 1.5MB is a yawn as is the reduced performance. I wouldn’t write a game in Xamarin but a simple data-based iOS or Android application — sure. Most of the C# xaml and object-binding is supported by Xamarin and writing UI is trivial. The documentation is excellent — a phrase I rarely utter.

One last important plus — when using Xamarin you can now also code with UWP (universal Windows platform) and that same iPhone/Android application runs under Windows, which is great for testing and support.

Debugging UWP on-screen

Debug vs Release Mode

The worst thing I ran into was that apps that work fine in Debug mode may crash hard in Release mode. This makes debugging a pain because you can’t debug effectively in Release mode. This is really bad in UWP and moderate in iOS/Android.

  • have a tendency to fail only in release mode which is just awful because they fail outside of the app and aren’t debug-able. This is pretty yucky.

If you’re lucky these things cause debug output in debug mode or they generate exceptions (even though they don’t crash) or so they can be tracked down. A few times I had to play binary search (comment out piles of code until it runs … ad infinitum).

  • In release mode is far more aggressive and it may throw out stuff that you actually are using because the linkage isn’t clear. This causes incorrect messages such as method not available in this version of Xamarin. The fix is to manually bind the necessary code chunks at app launch via adding an argument to the Xamarin Init ->
List<Assembly> assembliesToInclude = new List<Assembly>();
assembliesToInclude.Add(typeof(my.domain.folder.file).GetTypeInfo().Assembly);
Xamarin.Forms.Forms.Init(e, assembliesToInclude);

Here the source file my.domain.folder.file’s assembly is bound early. This was necessary to get FromResource to work and load images (for example).

  • There are many methods that only work in the . In debug mode those may warn or error but in release mode they crash. This is painful to track down. Most modern apps (like mine) use async all over the place for performance and simplicity so most calls by default aren’t in the GUI thread.
  • Some of the arguments to Xaml are not as robust as Windows C#.
Debugging Android showing a phone screen-capture during debug.

iOS Support

The iOS support in Xamarin is very cool. The build/edit/debug all take place on a windows machine — except — the iOS-specific build takes place on a networked Mac (I’m using a headless Mac Mini). So I click Build on the desktop PC and it starts building, moves to the Mac Mini where it finishes, then wirelessly downloads the app to my testing iPad which starts running the app and which then connects to the debugger wirelessly.

Wow! Super.

Views and Templates

Xamarin has this strange artificial difference between normal C# controls and View-type controls. Any control that’s inside of templates or used in settings must be based on the View-types (they all have Cell in the name), although one view type can contain a set of standard controls so…

When you forget this and use the wrong types Xamarin will crash with a call stack of one line [external code] and no indication of what happened other than invalid cast. This code crashes with no stack

<ListView>
<ListView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding Tone}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Replace the single <Label… /> line with the Cell equivalent

<TextCell Text="{Binding Tone}" />

and it runs just fine. This cries out for static analysis in the xaml compiler.

Project Properties

One of the problems with all this multiplatform stuff is that the usual Visual Studio project properties (with great macros and nice editing) turns into messy os-specific stuff with hardcoded paths.

So, I spent almost a day trying to understand why the sample Bluetooth app worked fine but mine never discovered anything.

Changing stuff all over the app, putting test code earlier and earlier in the app, nothing helped. Finally I found that in one of the properties windows is a button that says “Package Manifest”. Clicking that produces a dialog with many tabs. The Capabilities tab has a line of many checkboxes, one of which says “Bluetooth”. Turning that on magically enabled Bluetooth.

Wow. This isn’t illogical but it sure is hard to find and much too quiet.

Home Wireless

Home automation in the wireless IOT era

Mark Zachmann

Written by

Entrepreneur, software architect, electrical engineer. Ex-academic.

Home Wireless

Home automation in the wireless IOT era

More From Medium

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade