Optimistic Networking with Reactor

A Love Story

Jason Larsen
The Swift Fox

--

The original Swift Love Story

Last time we talked about some pretty cool stuff we can do to build a more reactive iOS application using the Reactor architecture. Today we’ll investigate how we can keep in sync with data from the network and make our app faster with the power of optimism!

Let’s look at the Reactor architecture diagram for a quick refresher:

We send events to make the Reactor update our application state. The reactor handles events, updates the state, and then notifies all the subscribers. But what about asynchronous events?

Commands

Performing async events is likely going to be a common occurrence in your app. Reactor offers the Command API to help establish a consistent and safe way to perform asynchronous events

Hopefully the code inside execute looks similar to your usual networking functions. The difference here is we’ve wrapped it inside of a function which receives its own copy of the application state and reference to the Reactor. We don’t end up needing the state for anything here, but we use the Reactor reference to dispatch events upon network task completion.

Instant, Optimistic Network Results

Say we’re performing a different type of network request, perhaps adding a new player. Do we really want to wait for a response from the server before we can update our UI? Can you imagine liking a post on Facebook and waiting for the request to travel all the way to the Facebook and back to confirm our like was successfully recorded before seeing the thumb turn blue? Ain’t nobody got time for that! We want our app to feel fast and responsive!

What if we just assume the network request is successful and immediately update the UI? Then we can update with the real response later. Or, in the case of an error, we can reset to the original state. Let’s call this “optimistic networking.”

This code is similar to our FetchPlayers command, but we have added properties to our struct—this allows us to set up necessary data for our async Command. We also are firing events in a few more places:

  1. We optimistically add the new player to our state, and fire an event telling the reactor to update its current list of players with our optimistic list.
  2. Upon a successful request, we parse the response and update (for a second time) with the result the server returns. If the data is the same (if our optimism was correct) then we should see no difference.
  3. If our request came back with an error, then we reset the list back to where it was when we started, and display an error message to the user.

Conclusion

If you are using Reactor and doing any sort of of asynchronous operations then you want to use Commands!

Commands will help you handle async tasks in a consistent manner while leveraging the power of Reactor to keep your UI always in sync. And with almost no work at all, you can have the power of optimism to make your app feel faster.

--

--