Skip to content

Commit cc3d551

Browse files
mluisbrownmbrandonw
andcommitted
Update Tic-Tac-Toe to use enum state (#595)
* Update Tic-Tac-Toe to use enum state * wip * more swift compatability changes Co-authored-by: Brandon Williams <[email protected]>
1 parent d1467db commit cc3d551

File tree

4 files changed

+63
-57
lines changed

4 files changed

+63
-57
lines changed

Examples/TicTacToe/Sources/Core/AppCore.swift

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import LoginCore
55
import NewGameCore
66
import ReactiveSwift
77

8-
public struct AppState: Equatable {
9-
public var login: LoginState? = LoginState()
10-
public var newGame: NewGameState?
8+
public enum AppState: Equatable {
9+
case login(LoginState)
10+
case newGame(NewGameState)
1111

12-
public init() {}
12+
public init() { self = .login(.init()) }
1313
}
1414

1515
public enum AppAction: Equatable {
@@ -31,8 +31,8 @@ public struct AppEnvironment {
3131
}
3232

3333
public let appReducer = Reducer<AppState, AppAction, AppEnvironment>.combine(
34-
loginReducer.optional().pullback(
35-
state: \.login,
34+
loginReducer.pullback(
35+
state: /AppState.login,
3636
action: /AppAction.login,
3737
environment: {
3838
LoginEnvironment(
@@ -41,25 +41,23 @@ public let appReducer = Reducer<AppState, AppAction, AppEnvironment>.combine(
4141
)
4242
}
4343
),
44-
newGameReducer.optional().pullback(
45-
state: \.newGame,
44+
newGameReducer.pullback(
45+
state: /AppState.newGame,
4646
action: /AppAction.newGame,
4747
environment: { _ in NewGameEnvironment() }
4848
),
4949
Reducer { state, action, _ in
5050
switch action {
5151
case let .login(.twoFactor(.twoFactorResponse(.success(response)))),
5252
let .login(.loginResponse(.success(response))) where !response.twoFactorRequired:
53-
state.newGame = NewGameState()
54-
state.login = nil
53+
state = .newGame(.init())
5554
return .none
5655

5756
case .login:
5857
return .none
5958

6059
case .newGame(.logoutButtonTapped):
61-
state.newGame = nil
62-
state.login = LoginState()
60+
state = .login(.init())
6361
return .none
6462

6563
case .newGame:

Examples/TicTacToe/Sources/Views-SwiftUI/AppSwiftView.swift

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,20 @@ public struct AppView: View {
1212
self.store = store
1313
}
1414

15-
@ViewBuilder public var body: some View {
16-
IfLetStore(self.store.scope(state: \.login, action: AppAction.login)) { store in
17-
NavigationView {
18-
LoginView(store: store)
15+
public var body: some View {
16+
SwitchStore(self.store) {
17+
CaseLet(state: /AppState.login, action: AppAction.login) { store in
18+
NavigationView {
19+
LoginView(store: store)
20+
}
21+
.navigationViewStyle(StackNavigationViewStyle())
1922
}
20-
.navigationViewStyle(StackNavigationViewStyle())
21-
}
22-
23-
IfLetStore(self.store.scope(state: \.newGame, action: AppAction.newGame)) { store in
24-
NavigationView {
25-
NewGameView(store: store)
23+
CaseLet(state: /AppState.newGame, action: AppAction.newGame) { store in
24+
NavigationView {
25+
NewGameView(store: store)
26+
}
27+
.navigationViewStyle(StackNavigationViewStyle())
2628
}
27-
.navigationViewStyle(StackNavigationViewStyle())
2829
}
2930
}
3031
}

Examples/TicTacToe/Sources/Views-UIKit/AppViewController.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ class AppViewController: UINavigationController {
3535
super.viewDidLoad()
3636

3737
self.store
38-
.scope(state: \.login, action: AppAction.login)
38+
.scope(state: /AppState.login, action: AppAction.login)
3939
.ifLet(then: { [weak self] loginStore in
4040
self?.setViewControllers([LoginViewController(store: loginStore)], animated: false)
4141
})
4242

4343
self.store
44-
.scope(state: \.newGame, action: AppAction.newGame)
44+
.scope(state: /AppState.newGame, action: AppAction.newGame)
4545
.ifLet(then: { [weak self] newGameStore in
4646
self?.setViewControllers([NewGameViewController(store: newGameStore)], animated: false)
4747
})

Sources/ComposableArchitecture/SwiftUI/SwitchStore.swift

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ public struct SwitchStore<State, Action, Content>: View where Content: View {
6969
public struct CaseLet<GlobalState, GlobalAction, LocalState, LocalAction, Content>: View
7070
where Content: View {
7171
@EnvironmentObject private var store: StoreObservableObject<GlobalState, GlobalAction>
72-
let toLocalState: (GlobalState) -> LocalState?
73-
let fromLocalAction: (LocalAction) -> GlobalAction
74-
let content: (Store<LocalState, LocalAction>) -> Content
72+
public let toLocalState: (GlobalState) -> LocalState?
73+
public let fromLocalAction: (LocalAction) -> GlobalAction
74+
public let content: (Store<LocalState, LocalAction>) -> Content
7575

7676
/// Initializes a `CaseLet` view that computes content depending on if a store of enum state
7777
/// matches a particular case.
@@ -158,10 +158,9 @@ extension SwitchStore {
158158

159159
public init<State1, Action1, Content1>(
160160
_ store: Store<State, Action>,
161-
@ViewBuilder content: @escaping ()
162-
-> CaseLet<State, Action, State1, Action1, Content1>,
163161
file: StaticString = #file,
164-
line: UInt = #line
162+
line: UInt = #line,
163+
@ViewBuilder content: @escaping () -> CaseLet<State, Action, State1, Action1, Content1>
165164
)
166165
where
167166
Content == WithViewStore<
@@ -216,12 +215,14 @@ extension SwitchStore {
216215

217216
public init<State1, Action1, Content1, State2, Action2, Content2>(
218217
_ store: Store<State, Action>,
219-
@ViewBuilder content: @escaping () -> TupleView<(
220-
CaseLet<State, Action, State1, Action1, Content1>,
221-
CaseLet<State, Action, State2, Action2, Content2>
222-
)>,
223218
file: StaticString = #file,
224-
line: UInt = #line
219+
line: UInt = #line,
220+
@ViewBuilder content: @escaping () -> TupleView<
221+
(
222+
CaseLet<State, Action, State1, Action1, Content1>,
223+
CaseLet<State, Action, State2, Action2, Content2>
224+
)
225+
>
225226
)
226227
where
227228
Content == WithViewStore<
@@ -291,13 +292,15 @@ extension SwitchStore {
291292

292293
public init<State1, Action1, Content1, State2, Action2, Content2, State3, Action3, Content3>(
293294
_ store: Store<State, Action>,
294-
@ViewBuilder content: @escaping () -> TupleView<(
295-
CaseLet<State, Action, State1, Action1, Content1>,
296-
CaseLet<State, Action, State2, Action2, Content2>,
297-
CaseLet<State, Action, State3, Action3, Content3>
298-
)>,
299295
file: StaticString = #file,
300-
line: UInt = #line
296+
line: UInt = #line,
297+
@ViewBuilder content: @escaping () -> TupleView<
298+
(
299+
CaseLet<State, Action, State1, Action1, Content1>,
300+
CaseLet<State, Action, State2, Action2, Content2>,
301+
CaseLet<State, Action, State3, Action3, Content3>
302+
)
303+
>
301304
)
302305
where
303306
Content == WithViewStore<
@@ -384,14 +387,16 @@ extension SwitchStore {
384387
State4, Action4, Content4
385388
>(
386389
_ store: Store<State, Action>,
387-
@ViewBuilder content: @escaping () -> TupleView<(
388-
CaseLet<State, Action, State1, Action1, Content1>,
389-
CaseLet<State, Action, State2, Action2, Content2>,
390-
CaseLet<State, Action, State3, Action3, Content3>,
391-
CaseLet<State, Action, State4, Action4, Content4>
392-
)>,
393390
file: StaticString = #file,
394-
line: UInt = #line
391+
line: UInt = #line,
392+
@ViewBuilder content: @escaping () -> TupleView<
393+
(
394+
CaseLet<State, Action, State1, Action1, Content1>,
395+
CaseLet<State, Action, State2, Action2, Content2>,
396+
CaseLet<State, Action, State3, Action3, Content3>,
397+
CaseLet<State, Action, State4, Action4, Content4>
398+
)
399+
>
395400
)
396401
where
397402
Content == WithViewStore<
@@ -490,15 +495,17 @@ extension SwitchStore {
490495
State5, Action5, Content5
491496
>(
492497
_ store: Store<State, Action>,
493-
@ViewBuilder content: @escaping () -> TupleView<(
494-
CaseLet<State, Action, State1, Action1, Content1>,
495-
CaseLet<State, Action, State2, Action2, Content2>,
496-
CaseLet<State, Action, State3, Action3, Content3>,
497-
CaseLet<State, Action, State4, Action4, Content4>,
498-
CaseLet<State, Action, State5, Action5, Content5>
499-
)>,
500498
file: StaticString = #file,
501-
line: UInt = #line
499+
line: UInt = #line,
500+
@ViewBuilder content: @escaping () -> TupleView<
501+
(
502+
CaseLet<State, Action, State1, Action1, Content1>,
503+
CaseLet<State, Action, State2, Action2, Content2>,
504+
CaseLet<State, Action, State3, Action3, Content3>,
505+
CaseLet<State, Action, State4, Action4, Content4>,
506+
CaseLet<State, Action, State5, Action5, Content5>
507+
)
508+
>
502509
)
503510
where
504511
Content == WithViewStore<

0 commit comments

Comments
 (0)