Unidirectional Data Flow Architecture (Redux) in Swift

I’m a big fan of reusable and clean architectures using Swift. In my last project, I have implemented MVVM and Protocol Oriented Architecture it helped a lot of to separate the concerns. Also I had worked on couple IOS project followed MVC approaches. It is important to choosing a right architecture while starting a new project or adapting on with the legacy code.

I’ve to find a great roundup about iOS Architecture Patterns, introduces common architectures if you interesting too.

But there was the better way (in my humble opinion) mostly in my experiences MVVM is done a great job while keeping it lightweight and I did implement Unidirectional Data Flow (Redux) approach with the MVVM in Swift make a huge difference. It makes slightly better clean architecture, robust and testable, so important aspect

In this post, I try to explain why using Redux with Swift is better idea. 
First, we need to understand the fundamentals of the concept.

So let’s dive in;

What is Redux and Unidirectional Data Flow?

Redux is a flux implementation but slightly better implementation, it makes your application’s state more predictable. It first came out in Javascript world as a predictable state container for JavaScript apps with the powerful javascript library React.

Redux, simply makes your application’s state in single store object. So firing an action from your application/in view’s lifecycle state changes and your reducers for that action generate a new state.

This is how your application data flows if you implement Unidirectional Data Flow in Swift

Another explaination for Redux, you can read cartoon guide intro to Redux

Lets begin;

In this post, I’d used ReSwift by benjaminencz who created the Redux implementation on Swift.

ReSwift is a Redux-like implementation of the unidirectional data flow architecture in Swift. ReSwift helps you to separate three important concerns of your app’s components:

  • State: in a ReSwift app the entire app state is explicitly stored in a data structure. This helps avoid complicated state management code, enables better debugging and has many, many more benefits…
  • Views: in a ReSwift app your views update when your state changes. Your views become simple visualizations of the current app state.
  • State Changes: in a ReSwift app you can only perform state changes through actions. Actions are small pieces of data that describe a state change. By drastically limiting the way the state can be mutated, your app becomes easier to understand and it gets easier to work with many collaborators.
clipped from ReSwift website

Usage

In this simple example, I declared a BaseState as struct takes two states.
BaseReducer has registered their reducers.

LoadingState struct handles the state of showing loading spinner view or hiding the view, has isLoading property to know currently is loading? and it is type spinning in view or spinning in status whatever.

Then, declared LoadingAction has two structs , LoadingShowAction passes the type as payload and LoadingHideAction not included any payload.

Finally, LoadingReducer takes the action (LoadingShowAction or LoadingHideAction) and the current state and it generates a new state.

Simple.

So, at this point we can just dispatch an action, ie;

store.dispatch(LoadingShowAction(type: .Normal)) to show spinner
store.dispatch(LoadingHideAction()) to hide the spinner.

Dispatcher’s fires newState() method takes LoadingState, so our LoadingView (is a simple UIView to implement spinner) setType and hidden properitites changes are subscribed.

When dispatch methods fires, it dispatches actions, reducer change to state, the new state notified by the subscribers (subscribed VC’s), UI update automatically.

Benefits are;

  • Structure: All your actions, reducers are clearly separated each other, makes you isolated components.
  • Predictability is come for free. You’ll know how to sync the current state with actions and other parts of the application.
  • Maintainability. Store, State, Actions, and Reducers are simple structs, easy to maintain, test.
  • Organized Code. Any new team member can easily understand how things work. (.i.e How store took state, action dispatched to reducer and reducer generated a new state, then subscribed VC’s fired UI changes etc.)

Using Undirectional Data flow and MVVM does fantastic job for me, worth to try.

Please leave comments below if you have ideas, suggestions. 
That all for today.

Thanks for the reading.

Resources in this post


Like what you read? Give Seyhun AKYÜREK a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.