Latest 0.1.2
Homepage https://github.com/soxjke/Redux-ReactiveSwift
License MIT
Platforms ios 9.0, osx 10.10, watchos 2.0, tvos 9.0
Dependencies ReactiveSwift
Authors

Redux-ReactiveSwift

CI Status
Code coverage status
Version
License
Platform
Carthage compatible

This library focuses on predictable state container implementation inspired by JS Redux. It benefits from ReactiveSwift. Using functional reactive approach & predictable state containers one should be able to write more clean & testable code :)

Example

The basic usage is pretty straightforward – one can create a store with State and reducer(‘s) of type (State, Event) -> State

import Redux_ReactiveSwift

class ViewModel {
    enum ButtonAction {
        case plus
        case minus
    }
    private(set) lazy var itemQuantityStore = Store<Int, ButtonAction>(state: 1, reducers: [self.itemQuantityReducer])
    private func itemQuantityReducer(state: Int, event: ButtonAction) -> Int {
        switch (event) {
            case .plus: return state + 1;
            case .minus: return state - 1;
        }
    }
}

Further, there can be benefit of binding data from Store using ReactiveSwift’s UnidirectionaBinding:

class ViewController: UIViewController {
    @IBOutlet weak var quantityLabel: UILabel!
    @IBOutlet weak var plusButton: UIButton!
    @IBOutlet weak var minusButton: UIButton!
    lazy var viewModel = ViewModel()
    override func viewDidLoad() {
        super.viewDidLoad()
        quantityLabel.reactive.text <~ viewModel.itemQuantityStore.map(String.describing)
    }
}

To connect actions one can use ReactiveSwift’s Action:

extension ViewModel {
    func action(for buttonAction: ButtonAction) -> Action<(), (), NoError> {
        return Action {
            return SignalProducer<(), NoError> { [weak self] in
                self?.itemQuantityStore.consume(event: buttonAction)
            }
        }
    }
}

class ViewController {
...
    override func viewDidLoad() {
        super.viewDidLoad()
        quantityLabel.reactive.text <~ viewModel.itemQuantityStore.map(String.describing)
        plusButton.reactive.pressed = CocoaAction(viewModel.action(for: .plus))
        minusButton.reactive.pressed = CocoaAction(viewModel.action(for: .minus))
    }
}

State changing logic is completely in one place. Forever. If we’d like to have something more advanced we can benefit of reducers chain:

extension ClosedRange {
    func clamp(_ value : Bound) -> Bound {
        return self.lowerBound > value ? self.lowerBound
            : self.upperBound < value ? self.upperBound
            : value
    }
}

class ViewModel {
    private func itemQuantityClamper(state: Int, event: ButtonAction) -> Int {
        return (0...10).clamp(state)
    }
    private(set) lazy var itemQuantityStore = Store<Int, ButtonAction>(state: 1, reducers: [self.itemQuantityReducer, self.itemQuantityClamper]
}

or it can be done with a single reducer with benefit of some kind of functional applyMap:

// This one looks ugly because tuple splatting was removed in Swift 4, thanks Chris Lattner!
func applyMap<R1, R2>(f2: @escaping (R1, R2) -> R1, mapper: @escaping (R1) -> R1) -> (R1, R2) -> R1 {
    return { (arg1, arg2) -> R1 in
        return mapper(f2(arg1, arg2))
    }
}
...
    private(set) lazy var itemQuantityStore = Store<Int, ButtonAction>(state: 1, reducers: [applyMap(f2: self.itemQuantityReducer, mapper: ClosedRange.clamp((0...10))]

Due to functional reactive spirit of solution you’re limited only by your fantasy and Mr.Lattner’s "enhancements" to Swift language. Some more cases of Store usage can be found in tests spec:

https://github.com/soxjke/Redux-ReactiveSwift/blob/master/Redux-ReactiveSwift/Tests/StoreSpec.swift

Requirements

Installation

Redux-ReactiveSwift is available through CocoaPods. To install
it, simply add the following line to your Podfile:

pod 'Redux-ReactiveSwift'

Redux-ReactiveSwift is available through Carthage. To install
it, simply add the following line to your Podfile:

github "soxjke/Redux-ReactiveSwift"

Author

Petro Korienev, [email protected]

License

Redux-ReactiveSwift is available under the MIT license. See the LICENSE file for more info.

Latest podspec

{
    "name": "Redux-ReactiveSwift",
    "version": "0.1.2",
    "summary": "Simple Redux Store implementation over ReactiveSwift.",
    "description": "This library focuses on simple implementation of ReduxStore backed by ReactiveSwift mutable property.nStore combines power of Redux's state controlling obviousness with reactive bindings. One can act with the store like with property.",
    "homepage": "https://github.com/soxjke/Redux-ReactiveSwift",
    "license": {
        "type": "MIT",
        "file": "LICENSE"
    },
    "authors": {
        "Petro Korienev": "[email protected]"
    },
    "source": {
        "git": "https://github.com/soxjke/Redux-ReactiveSwift.git",
        "tag": "0.1.2"
    },
    "social_media_url": "https://twitter.com/soxjke",
    "platforms": {
        "ios": "9.0",
        "osx": "10.10",
        "watchos": "2.0",
        "tvos": "9.0"
    },
    "source_files": "Redux-ReactiveSwift/Classes/**/*",
    "dependencies": {
        "ReactiveSwift": [
            "3.0.0"
        ]
    },
    "pushed_with_swift_version": "4.0"
}

Pin It on Pinterest

Share This