@@ -35,17 +35,47 @@ final class AppCoordinator: BaseCoordinator<AppCoordinatorNavigationStep> {
3535
3636 private lazy var walletUseCase = useCaseProvider. makeWalletUseCase ( )
3737 private lazy var pincodeUseCase = useCaseProvider. makePincodeUseCase ( )
38-
39- init ( navigationController: UINavigationController , deepLinkHandler: DeepLinkHandler , useCaseProvider: UseCaseProvider ) {
38+ private lazy var lockAppScene = LockAppScene ( )
39+
40+ private lazy var unlockAppScene : UnlockAppWithPincode = {
41+ let viewModel = UnlockAppWithPincodeViewModel ( useCase: pincodeUseCase)
42+ let scene = UnlockAppWithPincode ( viewModel: viewModel)
43+
44+ self . bag <~ scene. viewModel. navigator. navigation
45+ . asObservable ( )
46+ . observeOn ( MainScheduler . asyncInstance)
47+ . do ( onNext: { [ weak self] userDid in
48+ switch userDid {
49+ case . unlockApp:
50+ self ? . appIsUnlockedEmitBufferedDeeplinks ( )
51+ self ? . restoreMainNavigationStack ( )
52+ }
53+ } )
54+ . asDriverOnErrorReturnEmpty ( )
55+ . drive ( )
56+ return scene
57+ } ( )
58+
59+ private let __setRootViewControllerOfWindow : ( UIViewController ) -> Void
60+ private let isViewControllerRootOfWindow : ( UIViewController ) -> Bool
61+
62+ init (
63+ navigationController: UINavigationController ,
64+ deepLinkHandler: DeepLinkHandler ,
65+ useCaseProvider: UseCaseProvider ,
66+ isViewControllerRootOfWindow: @escaping ( UIViewController ) -> Bool ,
67+ setRootViewControllerOfWindow: @escaping ( UIViewController ) -> Void
68+ ) {
4069 self . deepLinkHandler = deepLinkHandler
4170 self . useCaseProvider = useCaseProvider
42-
71+ self . __setRootViewControllerOfWindow = setRootViewControllerOfWindow
72+ self . isViewControllerRootOfWindow = isViewControllerRootOfWindow
4373 super. init ( navigationController: navigationController)
4474 }
4575
4676 override func start( didStart: Completion ? = nil ) {
4777 if walletUseCase. hasConfiguredWallet {
48- toMain ( lockIfNeeded : true )
78+ toMain ( displayUnlockSceneIfNeeded : true )
4979 } else {
5080 toOnboarding ( )
5181 }
@@ -69,7 +99,7 @@ private extension AppCoordinator {
6999 }
70100 }
71101
72- func toMain( lockIfNeeded lock : Bool = false ) {
102+ func toMain( displayUnlockSceneIfNeeded displayUnlockScene : Bool = false ) {
73103
74104 let main = MainCoordinator (
75105 navigationController: navigationController,
@@ -79,8 +109,8 @@ private extension AppCoordinator {
79109 )
80110
81111 start ( coordinator: main, transition: . replace, didStart: { [ unowned self] in
82- if lock {
83- self . lockApp ( )
112+ if displayUnlockScene {
113+ self . toUnlockAppWithPincodeIfNeeded ( )
84114 }
85115 } , navigationHandler: { [ unowned self] userDid in
86116 switch userDid {
@@ -89,42 +119,81 @@ private extension AppCoordinator {
89119 } )
90120 }
91121
122+ var hasConfiguredPincode : Bool {
123+ return pincodeUseCase. hasConfiguredPincode
124+ }
125+
92126 func toUnlockAppWithPincodeIfNeeded( ) {
93- guard pincodeUseCase. hasConfiguredPincode, !isCurrentlyPresentingLockScene else { return }
94-
95- let viewModel = UnlockAppWithPincodeViewModel ( useCase: pincodeUseCase)
96-
97- deepLinkHandler. appIsLockedBufferDeeplinks ( )
98-
99- topMostCoordinator. modallyPresent (
100- scene: UnlockAppWithPincode . self,
101- viewModel: viewModel
102- ) { [ unowned self] userDid, dismissScene in
103- switch userDid {
104- case . unlockApp:
105- dismissScene ( true , { [ unowned self] in
106- self . deepLinkHandler. appIsUnlockedEmitBufferedDeeplinks ( )
107- } )
108- }
127+
128+ guard hasConfiguredPincode, !isCurrentlyPresentingUnLockScene else {
129+ return
109130 }
131+
132+ setRootViewControllerOfWindow ( to: unlockAppScene)
133+ }
134+ }
135+
136+ private extension AppCoordinator {
137+
138+ func restoreMainNavigationStack( ) {
139+ setRootViewControllerOfWindow ( to: navigationController)
140+ }
141+
142+ func setRootViewControllerOfWindow( to viewController: UIViewController ) {
143+ __setRootViewControllerOfWindow ( viewController)
110144 }
111145}
112146
113147// MARK: - Lock app with pincode
114148extension AppCoordinator {
149+
115150 func appWillResignActive( ) {
116151 lockApp ( )
117152 }
153+
154+ func appDidBecomeActive( ) {
155+ unlockApp ( )
156+ }
118157}
119158
120159// MARK: - Private Lock app with pincode
121160private extension AppCoordinator {
161+
122162 func lockApp( ) {
123- toUnlockAppWithPincodeIfNeeded ( )
163+ print ( " 🔐 Trying to lock app " )
164+ if isCurrentlyPresentingUnLockScene || isCurrentlyPresentingLockScene {
165+ print ( " 🙅🏻♀️ Avoided locking app 🔒 " )
166+ return
167+ }
168+ deepLinkHandler. appIsLockedBufferDeeplinks ( )
169+ setRootViewControllerOfWindow ( to: lockAppScene)
170+ }
171+
172+ func unlockApp( ) {
173+ if isCurrentlyPresentingUnLockScene { return }
174+ guard isCurrentlyPresentingLockScene else { return }
175+ print ( " 🔓 Trying to unlock app " )
176+ if hasConfiguredPincode {
177+ toUnlockAppWithPincodeIfNeeded ( )
178+ } else {
179+ restoreMainNavigationStack ( )
180+ appIsUnlockedEmitBufferedDeeplinks ( )
181+ }
124182 }
125183
184+ var isCurrentlyPresentingUnLockScene : Bool {
185+ guard hasConfiguredPincode else { return false }
186+ return isViewControllerRootOfWindow ( unlockAppScene)
187+ }
188+
126189 var isCurrentlyPresentingLockScene : Bool {
127- return topMostScene is UnlockAppWithPincode
190+ return isViewControllerRootOfWindow ( lockAppScene)
191+ }
192+
193+ func appIsUnlockedEmitBufferedDeeplinks( delayInSeconds: TimeInterval = 0.2 ) {
194+ DispatchQueue . main. asyncAfter ( deadline: DispatchTime . now ( ) + delayInSeconds) { [ weak self] in
195+ self ? . deepLinkHandler. appIsUnlockedEmitBufferedDeeplinks ( )
196+ }
128197 }
129198}
130199
0 commit comments