I have the following code, heavily inspired by the TicTacToe example project:
import ComposableArchitecture
struct Session: Equatable {
let token: String
}
@Reducer(state: .equatable)
enum AppRootFeature {
case loggedIn(AuthenticatedFeature)
case loggedOut(AuthenticationFeature)
public static var body: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case let .loggedOut(.authenticatedSuccessfully(token)):
state = .loggedIn(AuthenticatedFeature.State(token: token))
return .none
case .loggedOut:
return .none // Ignore the rest
case let .loggedIn(state):
print(state)
return .none // Ignore unless we would have log out functionality
}
}
.ifCaseLet(\.loggedOut, action: \.loggedOut) {
AuthenticationFeature()
}
.ifCaseLet(\.loggedIn, action: \.loggedIn) {
AuthenticatedFeature()
}
}
}
@Reducer
struct AuthenticatedFeature {
@ObservableState
struct State: Equatable {
let token: String
}
enum Action {
case showUser
case showOrder
}
var body: some Reducer<State, Action> {
Reduce { state, action in
switch action {
case .showUser:
return .none
case .showOrder:
return .none
}
}
}
}
@Reducer
struct AuthenticationFeature {
@Dependency(\.authentication) var authentication
@ObservableState
struct State: Equatable { }
enum Action {
case logIn
case authenticationError(Error)
case authenticatedSuccessfully(token: String)
}
var body: some Reducer<State, Action> {
Reduce { state, action in
switch action {
case .logIn:
return .run { send in
do {
let token = try await authentication.authenticate()
await send(.authenticatedSuccessfully(token: token))
} catch let error {
await send(.authenticationError(error))
}
}
case let .authenticationError(error):
print(error)
return .none // Not handled ATM
case .authenticatedSuccessfully:
return .none // Only interesting for root feature
}
}
}
}
When I trigger the .logIn
Action in the AuthenticationFeature
, it will trigger the right actions (.authenticatedSuccessfully
is received) but the parent feature AppRootFeature
does not receive the Action.
I cannot find any significant difference between the TicTacToe example and my code anymore, yet when I run the TicTacToe example it will propagate the actions of the Login feature where mine doesn't