Why every mobile developer should be reactive

Guest Blogger

Paul BettsPaul Betts is a C# Hacker at GitHub, and is the author of several open source .NET projects, including Refit, Splat! and Akavache. You can find Paul on his blog, Twitter, and speaking about reactive at Xamarin Evolve 2014.

Reactive Programming on iOS and Android

Almost every mobile application involves some sort of asynchronous operation – network requests, geolocation APIs, and even iOS’s Alert Views involve operations that call back your code. Using these asynchronous operations effectively are critical to creating great mobile experiences.

RxWriting well-tested, maintainable code that incorporates many async operations however, is easier said than done! Luckily, the C# language has several great tools at our disposal to help us out. C# 5.0’s async/await keywords are a huge boost to being able to write great async code, and today I’ll be talking about a great library that can be used alongside async/await to manage and compose Events together.

The Reactive Extensions for .NET is a library written by Microsoft that extends LINQ Queries to apply to asynchronous events and callbacks. On Xamarin.Mac, this library is built into the framework and can be referenced via the “Add Reference…” dialog, and on Xamarin.iOS and Xamarin.Android, this library can be found on both NuGet as well as the Xamarin Component Store.

Events as Lists

Before we jump into the details of Rx, we need to believe that Events and Lists are the same thing. How so? Consider IEnumerable – this type represents “a Sequence of items in a particular order that may or may not end” (for example, if I have IEnumerable digitsOfPi, I can always get more items!)

LINQ lets us take sequences (aka Lists) and apply operators such as Select and Where to these lists, in order to create a new List that represents more interesting data. The result is itself an IEnumerable that we can simply assign to a variable, and even combine with more operators later to derive a new result.

var applesPerShipment = new[] { 100, 100, 400, 300, };

var averageApplesPerShipment = applesPerShipment.Average();

var extraApples = applesPerShipment
    .Select(appleCount => appleCount - averageApplesPerShipment);

However, if we think about Events, we realize like an event like “KeyUp” is really just, “A Sequence of Items in a particular order that may or may not end” too! Data is coming in asynchronously to the KeyUp event, but the data is still an Item, and if we can step back and look at the KeyUp event over time, we can see a Sequence of Items too.

So, if Events and Lists are both the same, why can’t we apply the same LINQ operations to Events that we can to Lists? We should be able to build interesting events and assign them to variables, just like we do with Lists.

This is the core idea behind the Reactive Extensions, allowing us to compose events together to orchestrate asynchrony and describe complex relationships between events. However, to do it, we’ll need a new type that represents an Event, called IObservable. With it, we can use LINQ operators on incoming events

IObservable incomingAppleShipment;

var extraApplesForThisShipment = incomingAppleShipments
    .Select(x => x - averageApplesPerShipment);

extraApplesForThisShipment
    .Subscribe(x => Console.WriteLine("Cool, {0} more apples than usual!", x);

Turning Events into Observables

Observables are great, but how do we get them? One way to convert existing code into something that we can use Rx operators on, is via a Subject. This type is an Observable that you can control by hand:

var subject = new Subject();
subject.Subscribe(x => Console.WriteLine("Got an item: {0}", x);

subject.OnNext(4);
>>> Got an item: 4

subject.OnNext(6);
>>> Got an item: 6

We can use the Subject class to wrap event classes – here, we’re creating an IEventListener implementation that is also an IObservable:

class ObservableSensorListener : Java.Lang.Object, ISensorEventListener, IObservable
{
    readonly Subject sensorEvent = new Subject();

    public ObservableSensorListener(SensorManager sm)
    {
        inner = Disposable.Create(() => sm.UnregisterListener(this));
    }

    public void OnSensorChanged(SensorEvent e)
    {
        // NB: e.Values[0] == X axis ("left / right" from the perspective
        // of looking at the phone)
        sensorEvent.OnNext(e.Values[0]);
    }

    public IDisposable Subscribe(IObserver observer)
    {
        return sensorEvent.Subscribe(observer);
    }
}

Summarizing data with Rx

Often, raw sensor data from mobile devices is very erratic and jittery – this data is difficult to analyze or determine when meaningful events are happening. Let’s use Rx to clean up this data a bit by averaging it – we’ll slide an eight point “window” along the timeline, and for each set of eight data points, we’ll use the average of those points instead:

var smoothedPoints = listener
    .Buffer(8 /*points*/, /*move*/ 1 /*point at a time*/)
    .Select(xs => xs.Average());

reactive-extensions-screenshot

Check out the GitHub repository for this demo.

Learn More!

Here’s a few more resources to learn more about Rx:

Discuss this blog post in the Xamarin Forums

0 comments

Discussion is closed.

Feedback usabilla icon