If you can make apps on Android, iOS and Windows simultaneously, then you can save lots of time and money. Xamarin is a tool for doing just that – so we got Stanton from our own dev team to check it out…

The battle of the eco-systems rages on – Android vs iOS. Windows barely gets a foot in the door. It can therefore be frustrating and expensive if you want to get your app to as many people as possible. In order to release an app on both Android and iOS, for example; it can take double the developers, double the languages, double the libraries, double the time… and ultimately double the money too. So it’s no surprise that several tools have emerged, which claim to bridge the chasm. One of the most popular options comes from Xamarin – a company recently acquired by Microsoft.

I recently plunged into the weird and wonderful world of Xamarin for a week. This was lots of fun. I aimed to craft one app which can run on Android, iOS and Windows phones. The results pleasantly surprised me.

Picture of a wizard

Geoffrey Bluethistle the Third – Our Office Wizard

Geoff The Wizard the App

I decided to build a small app using our office mascot – our very own Geoff the Wizard. Geoff made his debut on the web. There he showed his magic and made predictions about the EU vote. It was time to bring him out of hibernation and put him to work.

The app is a super simple idea. Faced with any yes/no question, the user presses a button to ask Geoff. Consequently, Geoff will first summon his mystical energies and then point to either “yes” or “no” . In truth, the choice is random – a fun way to decide things, instead of just tossing a coin.

Attempt 1: Using A Model-View-Presenter Pattern

Xamarin provides an IDE. (An IDE is a souped up text-editor you write your code into). The coding is done in C#. This felt similar to the Java  I use as an Android Developer.

A screenshot of Xamarin Studio

Xamarin Studio – The IDE

Any Xamarin “solution” is broken into several folders (or “projects”). First of all, there is one for the shared code-base; then one for each platform (e.g. Android, iOS, Windows); and lastly, one for tests. When you click “Build”, Xamarin will make your app from files in both the shared folder and the relevant device folder.

Straight away, this structure forces you to decide how to separate your app’s central logic from the user interface. In my view, this is a helpful division to make early anyway. Obviously, you want to put as much as you can into the shared folder, where it will be reused for every platform.

Although each app starts from code in its platform folder, it pulls in bits from the shared folder afterwards.

Technical Bit :

(Skip to the end of the blue text if you want)

I wrote the interface twice – firstly for Android, and secondly for iOS. With each, I was able to use the same classes and functions I was familiar with – those provided by the platforms themselves. Xamarin just wraps them in a wafer-thin C# wrapper. Hence the code seems like regular Android or iOS code. You can see below, for example, how close this approach is to regular Android code:

Android Java:

public class MainActivity extends Activity implements GeoffViewable {

    private static final int FULL_COLOUR_RANGE = 256;

    private ImageView imageView;
    private GeoffPresenter presenter;
    private TextView yes;
    private TextView no;

    @Override
    protected void onCreate(Bundle savedInstanceState){

        super.onCreate (savedInstanceState);
        setContentView (R.layout.activity_main);
        requestWindowFeature (Window.FEATURE_NO_TITLE);

        presenter = new GeoffPresenter (this);

        Button button = (Button) findViewById (R.id.myButton);
        imageView = (ImageView) findViewById (R.id.geoff_image_view);
        yes = (TextView) FindViewById (R.id.yes);
        no = (TextView) FindViewById (R.id.no);

        button.setOnClickListener(new View.OnClickListener(){
            {
                @Override
                public void onClick(View v){
                    presenter.AskGeoff();
                }
        };

        Reset();
    }

 

Xamarin C# :

 public class MainActivity : Activity, GeoffViewable
{
    static int fullColorRange = 256;

    ImageView imageView;
    GeoffPresenter presenter;
    TextView yes;
    TextView no;

    protected override void OnCreate (Bundle savedInstanceState)
    {
        base.OnCreate (savedInstanceState);
        Window.RequestFeature (Android.Views.WindowFeatures.NoTitle);
        SetContentView (Resource.Layout.Main);

        presenter = new GeoffPresenter (this);
        random = new Random();

        Button button = FindViewById<Button> (Resource.Id.myButton);
        imageView = FindViewById<ImageView> (Resource.Id.geoff_image_view);
        yes = FindViewById<TextView> (Resource.Id.yes);
        no = FindViewById<TextView> (Resource.Id.no);

        button.Click += delegate
        {
            presenter.AskGeoff();
        };

    Reset();



}

 

This structure lends itself to the “Model-View-Presenter” pattern. First I put a ‘Viewable’ interface in the shared folder. Secondly, in the platform-specific folders, I wrote the relevant class for a single screen (either ‘Activity’ for Android, or ‘ViewController’ for iOS). Both of these implement that ‘Viewable’ interface. Finally I made a GeoffPresenter class in the shared folder. The  Viewable objects make a ‘GeoffPresenter’ and delegate the logic to it.

I found this approach to be fairly easy. It was like I was a carpenter who can use the same saws, hammers and chisels he always has. Except that the handles happen to be wrapped in cellophane – no big difference.

Attempt 2: Using Xamarin Forms

Feeling quite pleased with myself, I embarked on my second adventure. I set about making the same app using “Xamarin Forms”. Don’t be confused by the name – it isn’t just about the kind of forms you fill in. Rather it’s a whole library to make user interfaces.

This library allows you to put almost everything in the shared-folder – even the interface itself. In theory this should mean even less work. However, in reality, I took time to learn all the new bits and pieces.

So I started from scratch again. Also, this time, I added the Windows Phone platform.

The plus-side of this approach was that I could share much more of the code. I hardly touched the platform folders because Xamarin automatically filled them with the right files. All I did was put the images in the right places.

On the other hand, I also made a few unpleasant discoveries:

  1. You cannot use Xamarin Studio to make Windows Phone apps. Instead, you need Visual Studio on a Windows machine. I imported the same code-base but the IDE was pretty different.
  2. Things that behaved properly on an iPhone simulator would act differently  on Windows. Especially annoying was a glitch caused by swapping the images: the ‘Ask Geoff’ button briefly jumped – to the top of the screen and back again. In the end I found a clumsy work-around, but it’s a shame they hadn’t already solved these problems.
  3. The answers to my questions were harder to unearth. Even when I found fixes online, they were poorly explained. So I hope this improves with time, as more developers volunteer their solutions for common problems.

Using Xamarin Forms, it was like I was a carpenter who swapped all his regular tools for a different set. I now had an electric drill instead of a hand-drill; a jigsaw instead of my trusty hand-saw and a flathead instead of my Philips screwdriver. And just as I thought I’d got a handle on these tools, I found they react differently to different types of wood. Hopefully you follow the analogy.

Nevertheless, I was still happy – I had coded an app once, and it runs well on Android, iOS and Windows phones.

An iOS phone showing Geoff the wizard.

Geoff in Xamarin App Form

Lessons Learned

In conclusion, here are my thoughts from a week immersed in Xamarin:

  1. Xamarin does not cut out the need to learn each platform. To get the best out of Xamarin, you still need a good knowledge of how they work.
  2. Xamarin is not a “Hybrid Approach”. Although I heard it called this, it isn’t accurate, because a Xamarin app isn’t half-way between being a web app and a mobile app – it is fully a mobile app. It has all the performance and features that this entails.
  3. Xamarin offers flexibility. I explored two approaches, but I read that there were many shades in-between. This is important for projects that evolve over time.
  4. For the right projects, this software could save lots of time and money.
  5. Most of all, I would gladly visit the world of Xamarin again.

My code is on Github:

  1. Model-View-Presenter version
  2. Xamarin Forms version

Further reading