Last active
July 11, 2022 22:43
-
-
Save tobitech/911600cfe873eb82321cc3328b4824cb to your computer and use it in GitHub Desktop.
A SwiftUI app using The Composable Architecture.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ComposableArchitecture | |
import SwiftUI | |
let appReducer: Reducer<AppState, AppAction, AppEnvironment> = Reducer.combine( | |
onboardingReducer | |
.optional() | |
.pullback( | |
state: \AppState.onboarding, | |
action: /AppAction.onboarding, | |
environment: { _ in OnboardingEnvironment() } | |
), | |
Reducer { state, action, _ in | |
switch action { | |
case let .onboarding(.loginResponse(user)): | |
// not firing | |
state.loggedInUser = user | |
return .none | |
case .onboarding(.alert(.login)): | |
// not firing | |
return .none | |
case .onboarding(.alert(_)): | |
return .none | |
case .onboarding(.continueWithAppleButtonTapped): | |
// not firing | |
return .none | |
} | |
} | |
) | |
struct User: Equatable { | |
let email: String | |
} | |
struct AppState: Equatable { | |
var loggedInUser: User? | |
var onboarding: OnboardingState? | |
} | |
enum AppAction { | |
case onboarding(OnboardingAction) | |
} | |
struct AppEnvironment {} | |
struct AppView: View { | |
let store: Store<AppState, AppAction> | |
var body: some View { | |
WithViewStore(self.store) { viewStore in | |
if viewStore.loggedInUser != nil { | |
MainView() | |
} else { | |
OnboardingView( | |
store: Store( | |
initialState: OnboardingState(), | |
reducer: onboardingReducer, | |
environment: OnboardingEnvironment() | |
) | |
) | |
} | |
} | |
} | |
} | |
struct AppView_Previews: PreviewProvider { | |
static var previews: some View { | |
AppView( | |
store: Store( | |
initialState: AppState(), | |
reducer: appReducer, | |
environment: AppEnvironment() | |
) | |
) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ComposableArchitecture | |
import SwiftUI | |
let onboardingReducer = Reducer<OnboardingState, OnboardingAction, OnboardingEnvironment> { state, action, _ in | |
switch action { | |
case .continueWithAppleButtonTapped: | |
state.alert = .init( | |
title: TextState("Login"), | |
message: TextState("Are you sure you want to login?"), | |
primaryButton: .default(TextState("Login"), action: .send(.login)), | |
secondaryButton: .cancel(TextState("Cancel")) | |
) | |
return .none | |
case .alert(.dismiss): | |
state.alert = nil | |
return .none | |
case .alert(.login): | |
state.alert = nil | |
// TODO: Perform an async operation that will return user or error. | |
return Effect<User, Never>.future { callback in | |
DispatchQueue.main.asyncAfter(deadline: .now() + 3) { | |
let user = User(email: "[email protected]") | |
callback(.success(user)) | |
} | |
} | |
.map { OnboardingAction.loginResponse($0) } | |
case let .loginResponse(user): | |
// handle on parent reducer | |
return .none | |
} | |
} | |
struct OnboardingState: Equatable { | |
var alert: AlertState<OnboardingAction.AlertAction>? | |
} | |
enum OnboardingAction { | |
case alert(AlertAction) | |
case continueWithAppleButtonTapped | |
case loginResponse(User) | |
enum AlertAction: Equatable { | |
case dismiss | |
case login | |
} | |
} | |
struct OnboardingEnvironment {} | |
struct OnboardingView: View { | |
let store: Store<OnboardingState, OnboardingAction> | |
var body: some View { | |
WithViewStore(self.store) { viewStore in | |
VStack(alignment: .leading, spacing: 0.0) { | |
// ... | |
VStack(alignment: .center) { | |
SignInWithAppleButton() | |
.onTapGesture { | |
viewStore.send(.continueWithAppleButtonTapped) | |
} | |
// ... | |
} | |
} | |
.alert( | |
self.store.scope(state: \.alert, action: OnboardingAction.alert), | |
dismiss: .dismiss | |
) | |
} | |
} | |
} | |
struct OnboardingView_Previews: PreviewProvider { | |
static var previews: some View { | |
OnboardingView( | |
store: Store( | |
initialState: OnboardingState(), | |
reducer: onboardingReducer, | |
environment: OnboardingEnvironment() | |
) | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment