Protocols
The following protocols are available globally.
-
Protocol that marks something that can be actually dispatched into the
See moreStore
. It doesn’t have any particular requirement, and the protocol is actually used to simply mark a category of items. Currently theStore
is able to manage 3 types ofDispatchable
:SideEffect
,StateUpdater
andAction
(deprecated).Declaration
Swift
public protocol Dispatchable : CustomDebugStringConvertible
-
Protocol implemented by a dispatchable that wants to be dispatched in response to a notification
See moreDeclaration
Swift
public protocol NotificationObserverDispatchable : Dispatchable
-
Protocol implemented by a dispatchable that wants to be dispatched in response to a change of the state
See moreDeclaration
Swift
public protocol StateObserverDispatchable : Dispatchable
-
Protocol implemented by a dispatchable that wants to be dispatched in response to the dispatch of another dispatchable
See moreDeclaration
Swift
public protocol DispatchObserverDispatchable : Dispatchable
-
Protocol implemented by a dispatchable that wants to be dispatched when the store starts
See moreDeclaration
Swift
public protocol OnStartObserverDispatchable : Dispatchable
-
An action represents an event that leads to a change in the state of the application. It can be triggered from a user action, from a system event or any event in general.
See moreDeclaration
Swift
@available(*, deprecated, message: "Use AnyStateUpdater instead") public protocol Action : Dispatchable
-
Action
can implement this protocol to perform side effects when an instance is dispatched.A side effect is nothing more than a piece of code that can interact with external services or APIs (e.g., make a network request, get information from the disk and so on). Side effects are needed because the
updatedState(currentState:)
function (which is the only other operation that is performed when an action is dispatched) must be pure and therefore it cannot interact with disk, network and so on.Dependencies
You can see from the
See moresideEffect(currentState:previousState:dispatch:dependencies:)
signature that a side effect takes as input some dependencies. This is a form of dependency injection for the side effects. By using only methods coming from the dependencies (instead of relying on global imports), testing is much more easier since you can inject a mocked version of the things you need in the side effect. For example, in a test, you may want to inject a mocked version of the class that manages the API requests, in order to control the result of the network call.Declaration
Swift
@available(*, deprecated, message: "Use AnySideEffect instead") public protocol ActionWithSideEffect : Action
-
Type Erasure for
See moreAsyncAction
Declaration
Swift
@available(*, deprecated, message: "Use AnySideEffect or AnyStateUpdater instead") public protocol AnyAsyncAction
-
Protocol that represents an
async
action.An
AsyncAction
is just an abstraction overAction
that provides a way to structure your action.You typically use an
Async
action when you have to deal with operations that are asynchronous. In the most common scenario, you dispatch the initial action, execute an operation in the side effect and then dispatch a completed/failed action based on the result of the operation. If the action has a concept of progress, you can also dispatch progress actions.This protocol has as the main goal to standardize the way async actions are managed.
It is important to note that this is just a a convenience approach to something you can do anyway. You can for instance create three actions:
performOperation
,OperationCompleted
andOperationFailed
and achieve the same result.AsyncAction
just provide a way to abstract and simplify the processTip & Tricks
Since the
Action
protocol is very generic when it comes to the state type that should be updated, a pattern we want to promote is to put in your application a protocol like the following:protocol AppAsyncAction: AsyncAction { func updatedStateForLoading(currentState: inout AppState) // same for completed, failed and progress } extension AppAsyncAction { func updatedStateForLoading(currentState: State) -> State { guard var state = state as? AppState else { fatalError("Something went wrong") } self.updatedStateForLoading(currentState: &state) return state } // same for completed, failed and progress }
In this way you can save a lot of code since you can use your actions in the following way
See morestruct A: AppAsyncAction { func updatedStateForLoading(currentState: inout AppState) { state.props = action.payload } // same for completed, failed and progress }
Declaration
Swift
@available(*, deprecated, message: "Use SideEffect or StateUpdater instead") public protocol AsyncAction : Action, AnyAsyncAction
-
Declaration
Swift
public protocol AnySideEffectContext
-
Declaration
Swift
public protocol AnySideEffect : Dispatchable
-
A side effect is a single atom of the logic of your application. While you can actually use them as you desire, the idea is to implement in each side effect a meaningful, self contained, piece of logic that can be used from other pieces of you application (e.g., dispatched by a View Controller or by another side effect).
The
StateUpdater
is strongly tied to the state that it handles and the dependencies it has. This greatily simplifies the code written in normal situations. However, if you need to create updaters that are not strictly tied to a concrete types (e.g., in a library) you can useAnySideEffect
.### App Tips & Tricks To further simplify the usage of a
StateUpdater
you can add to your application a helper protocol/// assuming `AppState` is the type of your application's state and `DependenciesContainer` is the /// container of your dependencies protocol AppSideEffect: SideEffect where StateType == AppState, Dependencies == DependenciesContainer {}
By conforming to
See moreAppSideEffect
, you will get better autocompletionDeclaration
Swift
public protocol SideEffect : AnySideEffect
-
Protocol that the side effect dependencies container should implement
See moreDeclaration
Swift
public protocol SideEffectDependencyContainer : AnyObject
-
Protocol for the state of the applications. In Katana, all the relevant application information should be placed in a single struct that has to implement the
See moreState
protocol.Declaration
Swift
public protocol State
-
Declaration
Swift
public protocol AnyStateUpdater : Dispatchable
-
A
StateUpdater
is aDispatchable
that can be used to update theStore
state configuration.The
StateUpdater
is strongly tied to the state that it handles. This greatily simplifies the code written in normal situations. However, if you need to create updaters that are not strictly tied to a concrete state type (e.g., in a library) you can useAnyStateUpdater
.App Tips & Tricks
To futherly simplify the usage of a
StateUpdater
you can add to your application an helper protocol/// assuming `AppState` is the type of your application's state protocol AppStateUpdater: StateUpdater where StateType == AppState {}
By conforming to
See moreAppStateUpdater
, you will get better autocompletionDeclaration
Swift
public protocol StateUpdater : AnyStateUpdater
-
Declaration
Swift
public protocol AnyStore : AnyObject