Swift – How to handle network/async calls using Redux?

Posted on Posted in iOS

Overview


In this article, I will show how to deal with API requests in Redux architecture using ReSwift library. I assume that you already know Redux basics. If not I recommend you to check out Getting Started with ReSwift and a great free ebook: The Complete Redux Book.

Problem

Redux by itself doesn’t define where asynchronous operations should be handled. According to the concept, side effects should not be generated by Actions, State or Reducers. Therefore the last place where we could do that is Middleware which is actually designed for additional processing of Actions and generating side effects if needed.

Idea

I will show an approach in which we will implement two things:

  • Action representing a generic API call,
  • Middleware designed for these Actions, able to trigger network request and dispatch extra Actions once it’s finished.

Implementation


1. HttpRequest Protocol

Let’s first implement a protocol which will be later used to define endpoints conveniently. Each API Action should contain at least free essential information:

  1. resource – relative endpoint url,
  2. method – GET/POST etc.,
  3. optional JSON payload.

Also it should be able to define extra Actions in case of success or failure. Our RestClient will dispatch those Actions once the request is finished.

Of course you can add more properties like for example expectedStatusCode if needed, but to simplify implementation I added only essential fields.

2. ApiRequest implementation

Preferably we would like to have generic versions of methods onSuccess and onFailure to avoid boilerplate code in each endpoint definition (like parsing and unwrapping). That’s why base implementation of HttpRequest might be useful.

Having this class we can now easily start defining our API endpoints.

3. Middleware to handle API requests

The last thing we need is to implement a Middleware which will be able to process our API Actions and trigger specific HTTP requests.

Usage


Now we have all required elements, so we can easily define endpoints by subclassing ApiRequest.

Sample API Action

Dispatching

Summary


Implementation in this article is simplified to show an idea, not a production-ready solution.

Using this approach you gain a clean architecture in which:

  • Side effects like network requests are triggered by Middleware keeping State, Actions and Reducers simple.
  • Action for each API endpoint can be easily defined by subclassing ApiRequest.
  • API Actions allow to define additional Actions for success and failure.
  • API Actions are strongly typed and doesn’t require additional parsing or unwrapping.
  • Endpoint parameters (like credentials) can be passed through Action initializer.

Check out ReSwiftDemo project to see this code in action:
https://github.com/wojciech-kulik/ReSwiftDemo