The Bloc Pattern is a way to separate UI and Logic in SwiftUI codes
SwiftUIBloc
The Bloc Pattern is a way to separate UI and Logic in SwiftUI codes.
The Bloc is like a state machine where it accepts an event and produce a state.
Example
To run the example project, clone this repo, and open iOS Example.xcworkspace from the iOS Example directory.
Requirements
macOS(.v10_15), iOS(.v13), tvOS(.v14), watchOS(.v6)
Installation
Add this to your project using Swift Package Manager. In Xcode that is simply: File > Swift Packages > Add Package Dependency... and you're done. Alternative installations options are shown below for legacy projects.
CocoaPods
If you are already using CocoaPods, just add 'SwiftUIBloc' to your Podfile
then run pod install
.
Usage
- Create
Event
andState
:
enum CounterEvent: EventBase {
case increase
case decrease
}
enum CounterState: StateBase {
case initial
case counter(Int)
}
- Extend
Bloc
and overridemapEventToState
and useyield
to dispatch states:
final class CounterBloc: Bloc<CounterEvent, CounterState> {
private var count = 0
override func mapEventToState(_ event: CounterEvent) {
switch event {
case .increase:
count += 1
yield(.counter(count))
case .decrease:
count -= 1
yield(.counter(count))
}
}
}
Bloc Views
You can easily monitor bloc.state
in your view's body
and show the proper view base on that.
To remove some boilerplate there are couple of views you can use:
BlocBuilderView
BlocBuilderView
is a View
which requires a Bloc
and a @ViewBuilder
. BlocBuilderView
handles building the view in response to new states.
BlocBuilderView(bloc: bloc) { state in
// return view based on bloc state
}
You can control when the builder function should be called by providing buildWhen
function.
BlocBuilderView(bloc: bloc, buildWhen: {previousState, currentState in
// return true/false to determine whether or not
// to rebuild the view with state
}) {
// return view based on bloc's state
}
BlocListenerView
BlocListener
is a View
which takes a bloc
and invokes the listener
in response to state changes in the bloc.
BlocListenerView(bloc: bloc, listener: {state in
// do stuff here based on bloc's state
}) {
// return view
}
You can control when the listener function should be called by providing listenWhen
function.
BlocListenerView(bloc: bloc, listener: {state in
// do stuff here based on bloc's state
}, listenWhen: { (previousState, currentState) -> Bool in
// return true/false to determine whether or not
// to call listener with state
}) {
// return view
}
Author
Mehdi Sohrabi