@@ -12,11 +12,13 @@ class AppFlowCoordinator {
1212 private let container : AppDIContainer
1313 private let window : UIWindow
1414
15+ // 메모리 유지를 위한 Coordinator 참조
1516 private var splashCoordinator : SplashCoordinator ?
1617 private var mainCoordinator : MainCoordinator ?
17- private var loginCoordinator : LoginCoordinator ?
1818 private var onboardingCoordinator : OnboardingCoordinator ?
1919 private var lockScreenCoordinator : LockScreenCoordinator ?
20+ private var introCoordinator : IntroCoordinator ?
21+
2022
2123 init ( window: UIWindow , container: AppDIContainer ) {
2224 self . window = window
@@ -28,28 +30,27 @@ class AppFlowCoordinator {
2830 window. rootViewController = navigationController
2931 window. makeKeyAndVisible ( )
3032
33+ // 세션 만료 시: 모든 뷰를 엎고 다시 앱 시작
3134 SessionController . shared. routeToLogin = { [ weak self] in
32- self ? . showLoginFlow ( )
35+ DispatchQueue . main. async {
36+ AppDIContainer . shared. tokenStorage. clearAllTokens ( )
37+ UserDefaultsWrapper . shared. set ( false , forKey: UserDefaultsWrapper . Key. hasSeenIntro. rawValue)
38+ self ? . startApp ( )
39+ }
3340 }
3441
3542 let splashCoordinator = container. makeSplashCoordinator ( navigationController: navigationController)
3643 splashCoordinator. routerHandler = { [ weak self] router in
37- guard let self else { return }
44+ guard let self = self else { return }
3845 switch router {
39- case . login :
40- showLoginFlow ( )
46+ case . intro :
47+ showIntroFlow ( )
4148 case . main:
4249 showMainFlow ( )
43- case . onboarding:
44- showOnboardingFlow ( )
4550 case . alarm( let info, let address) :
4651 showMainFlow ( info: info, address: address, bottomType: . departure)
4752 case . lockScreen( let info, let address) :
4853 showLockScreenFlow ( info: info, address: address)
49- // case .realTime(let info, let address):
50- // showMainFlow(info: info, address: address, bottomType: .realTime)
51- // case .finishTime(let info, let address):
52- // showMainFlow(info: info, address: address, bottomType: .finish)
5354 case . detailRoute( let lat, let lon, let address) :
5455 print ( " lat : \( lat) , lon : \( lon) , address : \( address) " )
5556 }
@@ -61,26 +62,63 @@ class AppFlowCoordinator {
6162 private func showMainFlow( info: LegInfo ? = nil ,
6263 address: String ? = nil ,
6364 bottomType: MapBottomType = . search) {
65+
6466 let navigationController = UINavigationController ( )
6567 window. rootViewController = navigationController
66- mainCoordinator = container. makeMainCoordinator ( navigationController: navigationController)
67- mainCoordinator? . signoutFinish = { [ weak self] in
68+
69+ let mainCoordinator = container. makeMainCoordinator ( navigationController: navigationController)
70+ self . mainCoordinator = mainCoordinator
71+
72+ // [신규 유저 온보딩 흐름]
73+ // Main 화면(지도)을 깔아둔 상태에서, 그 위(Navigation 스택)에 온보딩을 얹습니다.
74+ mainCoordinator. routeToOnboarding = { [ weak self] in
75+ guard let self = self else { return }
6876 DispatchQueue . main. async {
69- self ? . showLoginFlow ( )
77+ let onboardingCoordinator = self . container. makeOnboardingCoordinator ( navigationController: navigationController)
78+
79+ // 온보딩(회원가입)이 성공적으로 끝났을 때
80+ onboardingCoordinator. onFinish = { [ weak self] success in
81+ DispatchQueue . main. async {
82+ // 위에 쌓여있던 온보딩 화면들을 싹 치우고 밑에 깔려있던 Main(지도)으로 복귀!
83+ navigationController. popToRootViewController ( animated: true )
84+
85+ // 집 주소가 등록되었으니, MainVC를 찔러서 현위치/마커를 새로고침하게 합니다.
86+ if let mainVC = navigationController. viewControllers. first as? MainViewController {
87+ mainVC. viewModel. setupLocation ( )
88+ mainVC. shouldShowWelcomeToast = true
89+
90+ mainVC. viewModel. isGuest = false
91+ }
92+
93+ self ? . onboardingCoordinator = nil
94+ }
95+ }
96+
97+ onboardingCoordinator. start ( )
98+ self . onboardingCoordinator = onboardingCoordinator // 메모리 유지
7099 }
71100 }
72- mainCoordinator? . lockScreenConfrim = { [ weak self] info, address in
101+
102+ // [락스크린 확인 흐름]
103+ mainCoordinator. lockScreenConfrim = { [ weak self] info, address in
73104 DispatchQueue . main. async {
74105 if let info, let address {
75- // self?.showMainFlow(info: info, address: address, bottomType: .realTime)
76106 self ? . showMainFlow ( info: info, address: address, bottomType: . detail)
77- // TODO: 상세화면 연동 로직 적용하기
78107 } else {
79108 self ? . showMainFlow ( )
80109 }
81110 }
82111 }
83- mainCoordinator? . start ( info: info, address: address, bottomType: bottomType)
112+
113+ // [회원 탈퇴 흐름]
114+ mainCoordinator. withdrawFinish = { [ weak self] in
115+ DispatchQueue . main. async {
116+ // 앱 데이터를 다 지웠으니, 스플래시부터 앱을 아예 새로 시작(리부팅)합니다!
117+ self ? . startApp ( )
118+ }
119+ }
120+
121+ mainCoordinator. start ( info: info, address: address, bottomType: bottomType)
84122 }
85123
86124 private func showLockScreenFlow( info: LegInfo ? = nil ,
@@ -94,7 +132,6 @@ class AppFlowCoordinator {
94132 switch router {
95133 case . lockScreen( let info, let address) :
96134 if let info, let address {
97- // TODO: 상세화면 연동하기 로직
98135 self ? . showMainFlow ( info: info, address: address, bottomType: . departure)
99136 } else {
100137 self ? . showMainFlow ( )
@@ -107,32 +144,21 @@ class AppFlowCoordinator {
107144 self . lockScreenCoordinator = lockScreenCoordinator
108145 }
109146
110- private func showLoginFlow ( ) {
147+ private func showIntroFlow ( ) {
111148 let navigationController = UINavigationController ( )
112149 window. rootViewController = navigationController
113150
114- let loginCoordinator = container. makeLoginCoordinator ( navigationController: navigationController)
115- loginCoordinator. onFinishWithExistUser = { [ weak self] isExist in
116- DispatchQueue . main. async {
117- isExist ? self ? . showMainFlow ( ) : self ? . showOnboardingFlow ( )
118- }
119- }
120- loginCoordinator. start ( )
121- self . loginCoordinator = loginCoordinator
122- }
123-
124- private func showOnboardingFlow( ) {
125- let navigationController = UINavigationController ( )
126- window. rootViewController = navigationController
151+ let introCoordinator = container. makeIntroCoordinator ( navigationController: navigationController)
127152
128- let onboardingCoordinator = container . makeOnboardingCoordinator ( navigationController : navigationController )
129- onboardingCoordinator . onFinish = { [ weak self] success in
153+ // 인트로에서 "게스트 모드로 시작하기" 등을 눌렀을 때 지도(Main)로 넘어갑니다.
154+ introCoordinator . onFinishWithGuest = { [ weak self] in
130155 DispatchQueue . main. async {
131- success ? self ? . showMainFlow ( ) : self ? . showLoginFlow ( )
156+ UserDefaultsWrapper . shared. set ( true , forKey: UserDefaultsWrapper . Key. hasSeenIntro. rawValue)
157+ self ? . showMainFlow ( )
132158 }
133159 }
134160
135- onboardingCoordinator . start ( )
136- self . onboardingCoordinator = onboardingCoordinator
161+ introCoordinator . start ( )
162+ self . introCoordinator = introCoordinator
137163 }
138164}
0 commit comments