Cross Platform (Android, iOS) app in F# with Reactive Extensions

If you love functional programming and want to write *native* cross-platform mobile apps (Android, iOS and even Windows Phone) and you know F#, you are set. The company that made this happen was [Xamarin](

For more info on Xamarin, read my blog article titled [Monkey business � write once, deploy on iOS, Android and Windows with Xamarin](

Until recently, you needed a paid subscription — but thanks to Microsoft, which acquired Xamarin, it is now open source.

F# belongs to Microsoft’s .NET family of languages, where the most well known language is C#. Note that F# also supports object-oriented programming, which comes in handy as both Java (typically used to develop Android apps) and Objective-C (typically used to develop iOS apps) are object-oriented.

All the business logic can be shared across platforms. Microsoft has graciously provided several [PCL]( (Portable Common Library) with a license that allows it to be used on any platform.

When using F#, your code is very succinct and much easier to understand than the equivalent (bloated) C# code. You can run snippets of F# code in the interpreter.

With Xamarin Forms, you can even have a common UI and it will be converted to native UI for each platform.

If you don’t know F#, but know some other functional language (Haskell, OCaml), you can learn F# easily.

[//]: # (todo add some representative F# code.)

Typically one would specify the UI declaratively in a markup file called [XAML]( and use databinding to communicate between the business model and the UI.

In this example, I will be using UI event handlers and an extension called “Microsoft Reactive Extensions”. This extension greatly simplifies writing apps that are asynchronous and event-based. Reactive Framework is push based (uses IObservable/IObserver), where you “Subscribe” for events by providing a callback. So a button can be considered as a source of push-based collection of click events. Or a timer can be used as a periodic source of events. With the Reactive Framework, Events become first-class.

IObservable/IObserver interfaces:

IObservable Interface
IDisposable Subscribe(
IObserver observer
Notifies the provider that an observer is to receive notifications.

// Example of Observable (timer) that fires every second:
let oneNumberEverySecond = Observable.Interval(TimeSpan.FromSeconds(1.))

// “SHOW NEXT WORD” button is clicked => show word after delay
d1 <- dispAfterDelay(timeSlider.Value, (snd wrd), wordsAndMeaningsTextEditor) // Subscribe to oneNumberEverySecond observable to update slider d2 <- oneNumberEverySecond.Subscribe(fun x -> oneSecTimerSubFun(int(x)))

I wrote a cross-platform (Android/iOS) app called Words, which can be used to test your vocabulary, to perhaps learn some new words. As shown above, my app uses Reactive framework to subscribe to Timer events and button-press events: given that Subscribe() returns an IDisposable, you can cancel these events by calling Dispose(). Implementing this functionality without the Reactive framework will be quite error-prone. Given that Events are first-class citizens, it makes testing of UI apps much easier as you can generate any event stream.

My use here of the Reactive framework barely scratches the surface of what is possible with it, namely: Delay, Throttle, Buffer, Sample, Merge, Combine.

You can install my Android App by clicking on its screenshot.


As this is a cross-platform Xamarin Forms app, you can build the iOS version also, as shown in the screenshot below. Though I created a single common declarative ui file, the buttons and sliders are native to the Android and iOS platforms.


But unlike Android where Google allows one to create apk file via the Ad-Hoc distribution channel, Apple doesn’t.

I plan to put this code on github. You can then build it on the Mac or Windows using the community editions of *Xamarin Studio* or *Visual Studio* respectively.

Update: I have put this app’s [code in github](

Leave a Reply

Your email address will not be published. Required fields are marked *