FluxSwift 0.2.2

FluxSwift 0.2.2

Maintained by Koji Murata.



 
Depends on:
RxSwift~> 5.0.1
RxRelay~> 5.0.1
 

FluxSwift 0.2.2

  • By
  • malt03

FluxSwift Build Status SwiftPM compatible License

FluxSwift is a completly typesafe Flux implementation using RxSwift.
Unlike Redux, Store is not a singleton.

Usage

Store

struct User: Store {
    let name: String
}

Action

In FluxSwift, unlike normal Flux, a reduce function is defined in Action.
This provides a type-safe implementation and prevents Fat Store.

struct ChangeName: Action {
    let newName: String
    func reduce(store: User) -> User? { // If you don't dispatch the Action to the Store, you can return nil.
        var tmp = store
        tmp.name = newName
        return tmp
    }
}

Register, Subscribe and Dispatch

let user: RegisteredStore<User> = User(name: "malt03").register() // register the store to Dispatcher
print(user.entity.name) // "malt03"
let disposable = user.subscribe(onNext: { (user) in print(user.name) }) // subscribe
ChangeName(newName: "malt04").dispatch() // dispatch

Define a nested Store

Set the value of childStores, an instance variable that conforms to the Store protocol.
If implemented as follows, when user is changed, the change will be detected in Session.

struct Session: Store {
    var token: String
    let user: RegisteredStore<User>

    var childStores: [AnyRegisteredStore] { [user.any()] }
}

Store with Codable

RegisteredStore also complies with Codable when Store conforms to Codable Protocol.

extension User: Codable {}
let json = try! JSONEncoder().encode(user) // { "name": "malt03" }
print(JSONDecoder().decode(RegisteredStore<User>.self, from: json).entity.name) // "malt03"

ThrowsAction

struct ChangeName: ThrowsAction {
    let newName: String
    func reduce(store: User) -> User? {
        var tmp = store
        store.name = newName
        return store
    }
}
try ChangeNameFromFile(nameFile: url).dispatch()

IdentifiableStore

By conforming to the IdentifiableStore Protocol, you can dispatch an Action only to the Store with the specified ID.

struct IdentifiableCounter: IdentifiableStore {
    let id: String
    var count = 0
    
    struct Increment: Action {
        func reduce(store: IdentifiableCounter) -> IdentifiableCounter? {
            var tmp = store
            tmp.count += 1
            return tmp
        }
    }
}

let a0 = IdentifiableCounter(id: "a").register()
let a1 = IdentifiableCounter(id: "a").register()
let b = IdentifiableCounter(id: "b").register()
IdentifiableCounter.Increment().dispatch(to: "a")
IdentifiableCounter.Increment().dispatch()
print(a0.entity.count) // 2
print(a1.entity.count) // 2
print(b.entity.count) // 1

Action with Observable

struct Store: FluxSwift.Store {
    var x: Int = 0
    
    struct Set: Action {
        let x: Int
        func reduce(store: Store) -> Store? { Store(x: x) }
    }
}

let store = Store().register()
let relay = PublishRelay<Int>()
let disposable = relay.dispatchAction(action: { Store.Set(x: $0) })

relay.accept(1)

Installation

SwiftPM (Recommended)

  • On Xcode, click File > Swift Packages > Add Package Dependency...
  • Input https://github.com/malt03/FluxSwift.git