diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index 956c2bb96..ae58d608a 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -405,8 +405,11 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, } - public func suspend() { - delegate.suspend() + public func suspendNetwork() { + delegate.suspendNetwork() + } + + public func suspendDatabase() { database.suspend() save() metadataFile.suspend() diff --git a/Frameworks/Account/AccountDelegate.swift b/Frameworks/Account/AccountDelegate.swift index 647921795..57c058768 100644 --- a/Frameworks/Account/AccountDelegate.swift +++ b/Frameworks/Account/AccountDelegate.swift @@ -50,7 +50,12 @@ protocol AccountDelegate { static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, completion: @escaping (Result) -> Void) - // For iOS, so we can suspend and resume properly. - func suspend() // Make sure no SQLite databases are open. + /// Suspend all network activity + func suspendNetwork() + + /// Suspend the SQLLite databases + func suspendDatabase() + + /// Make sure no SQLite databases are open and we are ready to issue network requests. func resume() } diff --git a/Frameworks/Account/AccountManager.swift b/Frameworks/Account/AccountManager.swift index 9c9b2182d..db8499ca3 100644 --- a/Frameworks/Account/AccountManager.swift +++ b/Frameworks/Account/AccountManager.swift @@ -164,9 +164,13 @@ public final class AccountManager: UnreadCountProvider { return accountsDictionary[accountID] } - public func suspendAll() { + public func suspendNetworkAll() { isSuspended = true - accounts.forEach { $0.suspend() } + accounts.forEach { $0.suspendNetwork() } + } + + public func suspendDatabaseAll() { + accounts.forEach { $0.suspendDatabase() } } public func resumeAll() { diff --git a/Frameworks/Account/FeedWrangler/FeedWranglerAccountDelegate.swift b/Frameworks/Account/FeedWrangler/FeedWranglerAccountDelegate.swift index faec7f9ea..f0af956f1 100644 --- a/Frameworks/Account/FeedWrangler/FeedWranglerAccountDelegate.swift +++ b/Frameworks/Account/FeedWrangler/FeedWranglerAccountDelegate.swift @@ -437,13 +437,17 @@ final class FeedWranglerAccountDelegate: AccountDelegate { // MARK: Suspend and Resume (for iOS) - /// Suspend the sync database so that it can close its SQLite file. - func suspend() { + /// Suspend all network activity + func suspendNetwork() { caller.cancelAll() + } + + /// Suspend the SQLLite databases + func suspendDatabase() { database.suspend() } - - /// Resume the sync database — let it reopen its SQLite file. + + /// Make sure no SQLite databases are open and we are ready to issue network requests. func resume() { database.resume() } diff --git a/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift b/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift index c493a3b14..ac42e7b73 100644 --- a/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift +++ b/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift @@ -554,13 +554,17 @@ final class FeedbinAccountDelegate: AccountDelegate { // MARK: Suspend and Resume (for iOS) - /// Suspend the sync database so that it can close its SQLite file. - func suspend() { + /// Suspend all network activity + func suspendNetwork() { caller.suspend() + } + + /// Suspend the SQLLite databases + func suspendDatabase() { database.suspend() } - - /// Resume the sync database — let it reopen its SQLite file. + + /// Make sure no SQLite databases are open and we are ready to issue network requests. func resume() { caller.resume() database.resume() diff --git a/Frameworks/Account/Feedly/FeedlyAccountDelegate.swift b/Frameworks/Account/Feedly/FeedlyAccountDelegate.swift index 1277630d7..5cff3405e 100644 --- a/Frameworks/Account/Feedly/FeedlyAccountDelegate.swift +++ b/Frameworks/Account/Feedly/FeedlyAccountDelegate.swift @@ -509,13 +509,17 @@ final class FeedlyAccountDelegate: AccountDelegate { // MARK: Suspend and Resume (for iOS) - /// Suspend the sync database so that it can close its SQLite file. - func suspend() { + /// Suspend all network activity + func suspendNetwork() { operationQueue.cancelAllOperations() + } + + /// Suspend the SQLLite databases + func suspendDatabase() { database.suspend() } - - /// Resume the sync database — let it reopen its SQLite file. + + /// Make sure no SQLite databases are open and we are ready to issue network requests. func resume() { database.resume() } diff --git a/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift b/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift index 21b1bbbf8..6f71ebbaf 100644 --- a/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift +++ b/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift @@ -31,10 +31,6 @@ final class LocalAccountDelegate: AccountDelegate { return refresher.progress } - func cancelAll(for account: Account) { - refresher.cancelAll() - } - func refreshAll(for account: Account, completion: @escaping (Result) -> Void) { refresher.refreshFeeds(account.flattenedWebFeeds()) { completion(.success(())) @@ -205,10 +201,14 @@ final class LocalAccountDelegate: AccountDelegate { // MARK: Suspend and Resume (for iOS) - func suspend() { - // Nothing to do + func suspendNetwork() { + refresher.cancelAll() } + func suspendDatabase() { + // Nothing to do + } + func resume() { // Nothing to do } diff --git a/Frameworks/Account/ReaderAPI/ReaderAPIAccountDelegate.swift b/Frameworks/Account/ReaderAPI/ReaderAPIAccountDelegate.swift index 488332edd..c47da8f6e 100644 --- a/Frameworks/Account/ReaderAPI/ReaderAPIAccountDelegate.swift +++ b/Frameworks/Account/ReaderAPI/ReaderAPIAccountDelegate.swift @@ -435,13 +435,17 @@ final class ReaderAPIAccountDelegate: AccountDelegate { // MARK: Suspend and Resume (for iOS) - /// Suspend the sync database so that it can close its SQLite file. - func suspend() { + /// Suspend all network activity + func suspendNetwork() { caller.cancelAll() + } + + /// Suspend the SQLLite databases + func suspendDatabase() { database.suspend() } - - /// Resume the sync database — let it reopen its SQLite file. + + /// Make sure no SQLite databases are open and we are ready to issue network requests. func resume() { database.resume() } diff --git a/iOS/AppDelegate.swift b/iOS/AppDelegate.swift index 5d4d694fa..5b4a7c4d8 100644 --- a/iOS/AppDelegate.swift +++ b/iOS/AppDelegate.swift @@ -303,14 +303,16 @@ private extension AppDelegate { func suspendApplication() { guard !isAnySceneInForeground else { return } + AccountManager.shared.suspendNetworkAll() + CoalescingQueue.standard.performCallsImmediately() for scene in UIApplication.shared.connectedScenes { if let sceneDelegate = scene.delegate as? SceneDelegate { sceneDelegate.suspend() } } - AccountManager.shared.saveAll() - AccountManager.shared.suspendAll() + + AccountManager.shared.suspendDatabaseAll() } }