Cleanup the background task that pauses the SDK when resigning active (#903)

* checking if the stop taskHandle is finished before stopping the bg task

* stopping the sync in background now works properly

* this will prevent the case in which if the app suspends and then is immediately foregrounded again, we do not start the sync

* now works as intended

* code improvement

* improved the code a bit
This commit is contained in:
Mauro
2023-05-19 10:28:30 +02:00
committed by GitHub
parent 03dece7bf4
commit 4e46c01945
5 changed files with 46 additions and 16 deletions
@@ -348,7 +348,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
hideLoadingIndicator() hideLoadingIndicator()
} }
userSession.clientProxy.stopSync() stopSync()
userSessionFlowCoordinator?.stop() userSessionFlowCoordinator?.stop()
guard !isSoft else { guard !isSoft else {
@@ -462,7 +462,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
navigationRootCoordinator.setRootCoordinator(SplashScreenCoordinator()) navigationRootCoordinator.setRootCoordinator(SplashScreenCoordinator())
userSession.clientProxy.stopSync() stopSync()
userSessionFlowCoordinator?.stop() userSessionFlowCoordinator?.stop()
let userID = userSession.userID let userID = userSession.userID
@@ -536,20 +536,24 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
@objc @objc
private func applicationWillResignActive() { private func applicationWillResignActive() {
MXLog.info("Application will resign active") MXLog.info("Application will resign active")
guard backgroundTask == nil else { guard backgroundTask == nil else {
return return
} }
backgroundTask = backgroundTaskService.startBackgroundTask(withName: "SuspendApp: \(UUID().uuidString)") { [weak self] in backgroundTask = backgroundTaskService.startBackgroundTask(withName: "SuspendApp: \(UUID().uuidString)") { [weak self] in
guard let self else { return } guard let self else {
return
stopSync() }
userSession?.clientProxy.stopSync {
backgroundTask = nil // No need to weakify self, this is a non escaping closure
isSuspended = true self.backgroundTask?.stop()
self.backgroundTask = nil
}
} }
isSuspended = true
// 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()
@@ -562,10 +566,11 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
backgroundTask?.stop() backgroundTask?.stop()
backgroundTask = nil backgroundTask = nil
if isSuspended { if isSuspended, userSession?.clientProxy.isSyncing == false {
isSuspended = false
startSync() startSync()
} }
isSuspended = false
} }
// MARK: Background app refresh // MARK: Background app refresh
@@ -152,16 +152,30 @@ class ClientProxy: ClientProxyProtocol {
return nil return nil
} }
} }
var isSyncing: Bool {
slidingSyncObserverToken != nil
}
func startSync() { func startSync() {
MXLog.info("Starting sync") MXLog.info("Starting sync")
guard slidingSyncObserverToken == nil else { guard !isSyncing else {
return return
} }
slidingSyncObserverToken = slidingSync?.sync() slidingSyncObserverToken = slidingSync?.sync()
} }
func stopSync(completionHandler: () -> Void) {
guard let slidingSyncObserverToken else {
MXLog.info("No sync is present")
return
}
stopSync()
while !slidingSyncObserverToken.isFinished() { }
completionHandler()
}
func stopSync() { func stopSync() {
MXLog.info("Stopping sync") MXLog.info("Stopping sync")
slidingSyncObserverToken?.cancel() slidingSyncObserverToken?.cancel()
@@ -178,7 +192,7 @@ class ClientProxy: ClientProxyProtocol {
} }
} }
} }
func createDirectRoom(with userID: String) async -> Result<String, ClientProxyError> { func createDirectRoom(with userID: String) async -> Result<String, ClientProxyError> {
await Task.dispatch(on: clientQueue) { await Task.dispatch(on: clientQueue) {
do { do {
@@ -81,9 +81,15 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol {
var allRoomsSummaryProvider: RoomSummaryProviderProtocol? { get } var allRoomsSummaryProvider: RoomSummaryProviderProtocol? { get }
var invitesSummaryProvider: RoomSummaryProviderProtocol? { get } var invitesSummaryProvider: RoomSummaryProviderProtocol? { get }
var isSyncing: Bool { get }
func startSync() func startSync()
/// Stops the sync usiung non escaping closure.
/// It's supposed to be used for the expiration handlers to guarantee its synchronous execution
func stopSync(completionHandler: () -> Void)
func stopSync() func stopSync()
func directRoomForUserID(_ userID: String) async -> Result<String?, ClientProxyError> func directRoomForUserID(_ userID: String) async -> Result<String?, ClientProxyError>
@@ -33,6 +33,8 @@ class MockClientProxy: ClientProxyProtocol {
var invitesSummaryProvider: RoomSummaryProviderProtocol? = MockRoomSummaryProvider() var invitesSummaryProvider: RoomSummaryProviderProtocol? = MockRoomSummaryProvider()
var avatarURLPublisher: AnyPublisher<URL?, Never> { Empty().eraseToAnyPublisher() } var avatarURLPublisher: AnyPublisher<URL?, Never> { Empty().eraseToAnyPublisher() }
var isSyncing: Bool { false }
internal init(userID: String, roomSummaryProvider: RoomSummaryProviderProtocol? = MockRoomSummaryProvider()) { internal init(userID: String, roomSummaryProvider: RoomSummaryProviderProtocol? = MockRoomSummaryProvider()) {
self.userID = userID self.userID = userID
@@ -43,6 +45,8 @@ class MockClientProxy: ClientProxyProtocol {
func startSync() { } func startSync() { }
func stopSync(completionHandler: () -> Void) { }
func stopSync() { } func stopSync() { }
func directRoomForUserID(_ userID: String) async -> Result<String?, ClientProxyError> { func directRoomForUserID(_ userID: String) async -> Result<String?, ClientProxyError> {
+1
View File
@@ -0,0 +1 @@
Stopping bg task when the app is suspended and the slidingSyncObserver is finished.