Fluxful
About
Fluxful is a minimalistic framework provides protocols and extensions for managing global application state following Flux pattern practices. Fluxful is written in Swift 5 and designed to produce standalone modules incapsulating distinct parts of application business logic. Fluxful modules provide tools allowing to easily follow store changes and render UI that always in sync with the current state.
You can read more about Flux pattern here
Fluxful flow diagram is similar to Redux. You can read about here
Installation
Swift Package Manager
Add "Fluxful" dependency in XCode
CocoaPods
pod 'Fluxful'
Add extension supporting store change notification and observering:
pod 'Fluxful/Reactive'
This will install the extension to Fluxful that enables possibility to observe store changes without using Combine or other libraries. With this extension you'll be able to subscribe to store changes by calling "addObserver" method and providing a change handler closure. "addObserver" returns a subscription object. Store subscription will be active until cancelled or the subscription object is disposed. You can use "notify" method inside the store action handlers and send notifications to subscribers with the information about which store properties has being changed by passing an array of "PartialKeyPath" objects.
Usage
First you need to declare actions:
struct SetAmountAction {
let value: UInt
}
struct FetchAmountAction {}
When you need to implement middleware, that handles specific actions by running asynchronous work and updates the store:
class MyMiddleware: Middleware {
var handlers: [ObjectIdentifier: Any] = [:]
init(dispatcher: Dispatcher) {
register(FetchAmountAction.self) { [weak dispatcher] (subject, action) in
/* Here you can run code in background or make API call */
// After that you should back to main thread and update the store
DispatchQueue.main.async { [weak store] in
dispatcher?.dispatch(SetAmountAction(value: /* Value received */))
}
// You can just intercept the action if it will not being handled in the store anyway
return .stop()
}
}
}
And the store is just a state container:
class MyStore: Store {
private(set) var amount = 0
var reducers: [ObjectIdentifier: Any] = [:]
var middlewares: [Middleware] = []
init() {
// Connect middleware
middlewares.append(MyMiddleware(dispatcher: self))
register(SetAmountAction.self) { (subject, action) in
// Mutate state
subject.amount = action.value
// Notify observers. When using with SwiftUI, this part would not needed. Don't forget to mark mutable properties with @Published
subject.notify(keyPathsChanged: [\MyStore.amount])
}
}
}
That's it! Now store will send notification every time its state changes when the action was dispatched to the store. By adding the observers with 'addObserver' method, you can track state changes and update UI accordingly.
Author
Natan Zalkin [email protected]
License
Fluxful is available under the MIT license. See the LICENSE file for more info.