Stop syncing on resign active and start again on resume (#232)

This commit is contained in:
ismailgulek
2022-10-17 18:23:12 +03:00
committed by GitHub
parent 0e90bff34c
commit 4fc7bf3d6c
2 changed files with 66 additions and 13 deletions
@@ -38,6 +38,7 @@ class UserSessionFlowCoordinator: Coordinator {
self.bugReportService = bugReportService self.bugReportService = bugReportService
setupStateMachine() setupStateMachine()
startObservingApplicationState()
} }
func start() { func start() {
@@ -48,6 +49,7 @@ class UserSessionFlowCoordinator: Coordinator {
// MARK: - Private // MARK: - Private
// swiftlint:disable:next cyclomatic_complexity
private func setupStateMachine() { private func setupStateMachine() {
stateMachine.addTransitionHandler { [weak self] context in stateMachine.addTransitionHandler { [weak self] context in
guard let self else { return } guard let self else { return }
@@ -56,7 +58,7 @@ class UserSessionFlowCoordinator: Coordinator {
case (.initial, .start, .homeScreen): case (.initial, .start, .homeScreen):
self.presentHomeScreen() self.presentHomeScreen()
case(_, _, .roomScreen(let roomId)): case(.homeScreen, .showRoomScreen, .roomScreen(let roomId)):
self.presentRoomWithIdentifier(roomId) self.presentRoomWithIdentifier(roomId)
case(.roomScreen(let roomId), .dismissedRoomScreen, .homeScreen): case(.roomScreen(let roomId), .dismissedRoomScreen, .homeScreen):
self.tearDownDismissedRoomScreen(roomId) self.tearDownDismissedRoomScreen(roomId)
@@ -70,6 +72,10 @@ class UserSessionFlowCoordinator: Coordinator {
self.presentSettingsScreen() self.presentSettingsScreen()
case (.settingsScreen, .dismissedSettingsScreen, .homeScreen): case (.settingsScreen, .dismissedSettingsScreen, .homeScreen):
self.dismissSettingsScreen() self.dismissSettingsScreen()
case (_, .resignActive, .suspended):
self.pause()
case (_, .becomeActive, _):
self.resume()
default: default:
fatalError("Unknown transition: \(context)") fatalError("Unknown transition: \(context)")
@@ -80,6 +86,17 @@ class UserSessionFlowCoordinator: Coordinator {
fatalError("Failed transition with context: \(context)") fatalError("Failed transition with context: \(context)")
} }
} }
private func startObservingApplicationState() {
NotificationCenter.default.addObserver(self,
selector: #selector(applicationWillResignActive),
name: UIApplication.willResignActiveNotification,
object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(applicationDidBecomeActive),
name: UIApplication.didBecomeActiveNotification,
object: nil)
}
private func presentHomeScreen() { private func presentHomeScreen() {
userSession.clientProxy.startSync() userSession.clientProxy.startSync()
@@ -272,4 +289,24 @@ class UserSessionFlowCoordinator: Coordinator {
navigationRouter.dismissModule() navigationRouter.dismissModule()
remove(childCoordinator: bugReportCoordinator) remove(childCoordinator: bugReportCoordinator)
} }
// MARK: - Application State
private func pause() {
userSession.clientProxy.stopSync()
}
private func resume() {
userSession.clientProxy.startSync()
}
@objc
private func applicationWillResignActive() {
stateMachine.processEvent(.resignActive)
}
@objc
private func applicationDidBecomeActive() {
stateMachine.processEvent(.becomeActive)
}
} }
@@ -35,6 +35,9 @@ class UserSessionFlowCoordinatorStateMachine {
/// Showing the settings screen /// Showing the settings screen
case settingsScreen case settingsScreen
/// Application has been suspended
case suspended
} }
/// Events that can be triggered on the AppCoordinator state machine /// Events that can be triggered on the AppCoordinator state machine
@@ -57,24 +60,37 @@ class UserSessionFlowCoordinatorStateMachine {
case showSettingsScreen case showSettingsScreen
/// The settings screen has been dismissed /// The settings screen has been dismissed
case dismissedSettingsScreen case dismissedSettingsScreen
/// Application goes into inactive state
case resignActive
/// Application goes into active state
case becomeActive
} }
private let stateMachine: StateMachine<State, Event> private let stateMachine: StateMachine<State, Event>
private var stateBeforeSuspension: State = .initial
init() { init() {
stateMachine = StateMachine(state: .initial) { machine in stateMachine = StateMachine(state: .initial)
machine.addRoutes(event: .start, transitions: [.initial => .homeScreen]) configure()
}
// Transitions with associated values need to be handled through `addRouteMapping` private func configure() {
machine.addRouteMapping { event, fromState, _ in stateMachine.addRoutes(event: .start, transitions: [.initial => .homeScreen])
switch (event, fromState) {
case (.showRoomScreen(let roomId), .homeScreen): stateMachine.addRouteMapping { event, fromState, _ in
return .roomScreen(roomId: roomId) switch (event, fromState) {
case (.dismissedRoomScreen, .roomScreen): case (.showRoomScreen(let roomId), .homeScreen):
return .homeScreen return .roomScreen(roomId: roomId)
default: case (.dismissedRoomScreen, .roomScreen):
return nil return .homeScreen
} case (.resignActive, _):
self.stateBeforeSuspension = fromState
return .suspended
case (.becomeActive, .suspended):
return self.stateBeforeSuspension
default:
return nil
} }
} }
} }