Swiftpack.co - Package - NicholasTD07/TDRedux.swift


CocoaPods Carthage compatible Swift Package Manager

Travis Codecov CocoaPods License

Yet another Redux written in Swift


Swift Package Manager

Add this repo as a dependency in your Package.swift file, for example:

import PackageDescription

let package = Package(
    name: "Example",
    dependencies: [
        .Package(url: "https://github.com/NicholasTD07/TDRedux.swift.git",
                 majorVersion: 2),


github "NicholasTD07/TDRedux.swift" ~> 2.0


pod 'TDRedux.swift', '~> 2.0'



A Store holds a State. A State is the entire internal state of an application, which could be anything.

You can

  • create a Store with a Reducer
  • dispatch Actions to change a Store's State
  • subscribe to changes happens to the State of a Store

Read more: Redux in Swift Part 1 - Store and State

Reducer Type

A Reducer is a function which takes an optional State and an Action and returns a new State, defined as the following:

class Store<State> {
    typealias Reducer = (State?, Action) -> State

Read more: Redux in Swift Part 1 - Reducer and Action


An Action describes what happened while it may carry some data, e.g. AddTodo(text: "buy milk") or ToggleTodo(atIndex: 1)

Action type is defined as

typealias Action = Any

Read more: Redux in Swift Part 1 - Reducer and Action

Reducer function

A helper function which wraps Reducers that take non-optional State and specific type of Action, so that: No more type-casting in hand written Reducers anymore. For example:

typealias CounterState = Int

enum CounterActions {
  case increase
  case decrease

let counterReducer: (CounterState, CounterActions) = /* ... */
let wrappedReducer: (CounterState?, Any) = Reducer(initialState: 0, reducer: counterReducer)

let counterStore = Store<CounterState>.init(with: wrappedReducer)


A helper function which combines an array of Reducers into one. For example:

typealias State = /* ... */
let arranOfReducers: [(State?, Any)] = [ /* ... */ ]
let combinedReducers: (State?, Any) = combineReducers(arranOfReducers)


It provides a third-party extension point between dispatching an action, and the moment it reaches the reducer.

Redux doc: Middleware

What's Experimental?

Everything in Store is final

Store and every property and methods in Store are defined as final.

Let me know if you think the Store need to be subclassed and overridden.


I am not too familiar with this concept in Redux and also I am not sure whether there are potential issues in my implementation or not.


TDRedux is released under the MIT license. See LICENSE for details.

Read More


Stars: 1
Help us keep the lights on


Used By

Total: 1


3.0.0 - Jun 2, 2019

  • Rename combine(reducers:) to combined(reducers:)
  • Update to Swift 5

2.0.1 - Nov 16, 2016

No functionality or API changes

2.0.0 - Oct 21, 2016

Breaking change

Made Action a protocol rather than a typealias of Any

Because if Action were a typealias of Any, then dispatch(_: Action/Any) could also dispatch AsyncActions

Renamed combineReducers(_:) to combine(reducers:)

What is needed to update from version 1 to 2?

Not much.

After you got the new release, v2.0.0

  • Try compile your project with it
  • Fix complier error where your Action types need to conform to Action
  • Fix compiler error where there's combineReducers(_:)


Safer code. For example, without this change, you could dispatch AsyncAction with dispatch(_:Action) method which won't have any expected effect.


  • Rename combineReducers to combine(reducers:) 3d52400
  • Make Action a protocol rather than a typealias of Any 7403e06
  • Everything is final by default after [SE-0117] 9d2a45b

1.7.0 - Oct 21, 2016


What's new?

  • Now you can subscribe to changes of a Store's State without caring what's the change

What's changed?

  • Mark all funcs in Store as final

1.6.0 - Oct 20, 2016

// fetchPosts: AsycAction
func fetchPosts(dispatch: @escaping Store.Dispatch) {

    api.fetchPosts { posts: [Post] in
        dispatch(Actions.fetchPosts(.success(posts: posts)))

store.dispatch(asyncAction : fetchPosts)