Re-enable and (hopefuly) simplify background app refresh handling

This commit is contained in:
Stefan Ceriu
2023-08-08 15:34:35 +03:00
committed by Stefan Ceriu
parent 35685db3c4
commit 8f22a5f435
@@ -24,12 +24,9 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
private let stateMachine: AppCoordinatorStateMachine private let stateMachine: AppCoordinatorStateMachine
private let navigationRootCoordinator: NavigationRootCoordinator private let navigationRootCoordinator: NavigationRootCoordinator
private let userSessionStore: UserSessionStoreProtocol private let userSessionStore: UserSessionStoreProtocol
/// Common background task to resume long-running tasks in the background.
/// When this task expiring, we'll try to suspend the state machine by `suspend` event.
private var backgroundTask: BackgroundTaskProtocol?
/// Task used while processing background app refreshes /// Common background task to continue long-running tasks in the background.
private var backgroundAppRefreshTask: BGAppRefreshTask? private var backgroundTask: BackgroundTaskProtocol?
private var isSuspended = false private var isSuspended = false
@@ -54,7 +51,6 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
private var userSessionObserver: AnyCancellable? private var userSessionObserver: AnyCancellable?
private var clientProxyObserver: AnyCancellable? private var clientProxyObserver: AnyCancellable?
private var networkMonitorObserver: AnyCancellable? private var networkMonitorObserver: AnyCancellable?
private var backgroundRefreshSyncObserver: AnyCancellable?
let notificationManager: NotificationManagerProtocol let notificationManager: NotificationManagerProtocol
@@ -543,10 +539,6 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
private func stopSync() { private func stopSync() {
userSession?.clientProxy.pauseSync() userSession?.clientProxy.pauseSync()
backgroundAppRefreshTask?.setTaskCompleted(success: true)
backgroundAppRefreshTask = nil
clientProxyObserver = nil clientProxyObserver = nil
} }
@@ -558,8 +550,6 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
userSession.clientProxy.startSync() userSession.clientProxy.startSync()
installBackgroundAppRefreshMonitor()
let identifier = "StaleDataIndicator" let identifier = "StaleDataIndicator"
func showLoadingIndicator() { func showLoadingIndicator() {
@@ -623,17 +613,13 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
backgroundTask?.stop() backgroundTask?.stop()
backgroundTask = nil backgroundTask = nil
backgroundAppRefreshTask?.setTaskCompleted(success: true)
backgroundAppRefreshTask = nil
} }
isSuspended = true isSuspended = true
#warning("Intentionally disabled until we understand certain deadlocks")
// This does seem to work if scheduled from the background task above // This does seem to work if scheduled from the background task above
// Schedule it here instead but with an earliest being date of 30 seconds // Schedule it here instead but with an earliest being date of 30 seconds
// scheduleBackgroundAppRefresh() scheduleBackgroundAppRefresh()
} }
@objc @objc
@@ -679,33 +665,24 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
} }
} }
private var backgroundRefreshSyncObserver: AnyCancellable?
private func handleBackgroundAppRefresh(_ task: BGAppRefreshTask) { private func handleBackgroundAppRefresh(_ task: BGAppRefreshTask) {
MXLog.info("Started background app refresh") MXLog.info("Started background app refresh")
backgroundAppRefreshTask = task
// This is important for the app to keep refreshing in the background // This is important for the app to keep refreshing in the background
scheduleBackgroundAppRefresh() scheduleBackgroundAppRefresh()
task.expirationHandler = { [weak self] in task.expirationHandler = {
MXLog.info("Background app refresh task expired") MXLog.info("Background app refresh task expired")
self?.stopSync() task.setTaskCompleted(success: true)
} }
guard let userSession, !userSession.clientProxy.isSyncing else {
return
}
startSync()
}
private func installBackgroundAppRefreshMonitor() {
guard let userSession else { guard let userSession else {
fatalError("User session not setup") return
} }
guard backgroundAppRefreshTask != nil else { if !userSession.clientProxy.isSyncing {
return startSync()
} }
// Be a good citizen, run for a max of 10 SS responses or 10 seconds // Be a good citizen, run for a max of 10 SS responses or 10 seconds
@@ -715,9 +692,12 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
.filter(\.isSyncUpdate) .filter(\.isSyncUpdate)
.collect(.byTimeOrCount(DispatchQueue.main, .seconds(10), 10)) .collect(.byTimeOrCount(DispatchQueue.main, .seconds(10), 10))
.sink(receiveValue: { [weak self] _ in .sink(receiveValue: { [weak self] _ in
guard let self else { return }
MXLog.info("Background app refresh finished") MXLog.info("Background app refresh finished")
self?.backgroundRefreshSyncObserver?.cancel() backgroundRefreshSyncObserver?.cancel()
self?.stopSync()
task.setTaskCompleted(success: true)
}) })
} }
} }