C# and F# Xamarin iOS Quick Start Projects

I’m starting to get into iOS development using Xamarin.

So to start out, I followed the Quick Start tutorials for Xamarin Forms but as a twist decided to also do it using F#. I didn’t just figure out how to do it in F# however, I used the following resources to help out:

You can find my implementations of the Quick Start on github at:

Xamarin Forms Quick Start in C# and F# on GitHub

Though I want to draw attention to one part of the project which was a puzzle for me given my current knowledge (or lack thereof) of F#.

Async Event Handlers in F#

In the Quick Start tutorial the Call button click is an async event handler. So this (taken from MainPage.xaml.cs):

async void OnCall(object sender, EventArgs e)
{
        if (await DisplayAlert(
                        "Dial a Number",
                        "Would you like to call " + translatedNumber + "?",
                        "Yes",
                        "No"))
        {
                var dialer = DependencyService.Get<IDialer>();
                if (dialer != null)
                        dialer.Dial(translatedNumber);
        }
}

So its an async event handler in C#, but how on earth do you do this in F#?

As F# has similar but different ways of doing async (that came before C# async) we need to code it differently. So here is the equivalent in F# (taken from MainPage.fs). Note that I’ve split it into two methods to make a bit clearer:

member this.makePhoneCall = async {
        let! ok = Async.AwaitTask(this.DisplayAlert("Dial a Number", sprintf "Would you like to call %s ?" translatedNumber, "Yes", "No"))
        if ok then
            let dialer = DependencyService.Get<IDialer>()
            if not(Object.ReferenceEquals(dialer, null))
            then dialer.Dial(translatedNumber) |> ignore
    }

member this.OnCall(sender : Object, e : EventArgs) =
    this.makePhoneCall |> Async.StartImmediate

One of the key differences between C# and F# async is that in F# the async block (async { ... } in makePhoneCall) is a specification; it does not execute the code. You need to specifically start it using Async.StartImmediate in OnCall. This method starts the async block immediately on the current thread which in this case is the UI thread (which is needed as we’re interacting with the UI).

Some resources I found really helpful: