diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index a8f99784c..d787bfa51 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -407,9 +407,16 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, public func suspend() { delegate.cancelAll(for: self) + delegate.suspend() + database.suspend() save() } - + + public func resume() { + database.resume() + delegate.resume() + } + public func save() { metadataFile.save() webFeedMetadataFile.save() diff --git a/Frameworks/Account/AccountDelegate.swift b/Frameworks/Account/AccountDelegate.swift index 3480a51cb..9ddecdbb7 100644 --- a/Frameworks/Account/AccountDelegate.swift +++ b/Frameworks/Account/AccountDelegate.swift @@ -50,5 +50,8 @@ protocol AccountDelegate { func accountWillBeDeleted(_ account: Account) 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. + func resume() } diff --git a/Frameworks/Account/AccountManager.swift b/Frameworks/Account/AccountManager.swift index a6483c939..f5e718adb 100644 --- a/Frameworks/Account/AccountManager.swift +++ b/Frameworks/Account/AccountManager.swift @@ -166,7 +166,11 @@ public final class AccountManager: UnreadCountProvider { public func suspendAll() { accounts.forEach { $0.suspend() } } - + + public func resumeAll() { + accounts.forEach { $0.resume() } + } + public func refreshAll(errorHandler: @escaping (Error) -> Void, completion: (() ->Void)? = nil) { let group = DispatchGroup() diff --git a/Frameworks/Account/FeedWrangler/FeedWranglerAccountDelegate.swift b/Frameworks/Account/FeedWrangler/FeedWranglerAccountDelegate.swift index f1b4352f4..13f868e81 100644 --- a/Frameworks/Account/FeedWrangler/FeedWranglerAccountDelegate.swift +++ b/Frameworks/Account/FeedWrangler/FeedWranglerAccountDelegate.swift @@ -438,6 +438,18 @@ final class FeedWranglerAccountDelegate: AccountDelegate { } } } + + // MARK: Suspend and Resume (for iOS) + + /// Suspend the sync database so that it can close its SQLite file. + func suspend() { + database.suspend() + } + + /// Resume the sync database — let it reopen its SQLite file. + func resume() { + database.resume() + } } // MARK: Private diff --git a/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift b/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift index efe734e1a..cc1dfa709 100644 --- a/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift +++ b/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift @@ -555,7 +555,18 @@ final class FeedbinAccountDelegate: AccountDelegate { } } - + + // MARK: Suspend and Resume (for iOS) + + /// Suspend the sync database so that it can close its SQLite file. + func suspend() { + database.suspend() + } + + /// Resume the sync database — let it reopen its SQLite file. + func resume() { + database.resume() + } } // MARK: Private diff --git a/Frameworks/Account/Feedly/FeedlyAccountDelegate.swift b/Frameworks/Account/Feedly/FeedlyAccountDelegate.swift index 9a8ce30c3..48db9fa41 100644 --- a/Frameworks/Account/Feedly/FeedlyAccountDelegate.swift +++ b/Frameworks/Account/Feedly/FeedlyAccountDelegate.swift @@ -510,4 +510,16 @@ final class FeedlyAccountDelegate: AccountDelegate { assertionFailure("An `account` instance should enqueue an \(FeedlyRefreshAccessTokenOperation.self) instead.") completion(.success(credentials)) } + + // MARK: Suspend and Resume (for iOS) + + /// Suspend the sync database so that it can close its SQLite file. + func suspend() { + database.suspend() + } + + /// Resume the sync database — let it reopen its SQLite file. + func resume() { + database.resume() + } } diff --git a/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift b/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift index 23d9dba61..21b1bbbf8 100644 --- a/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift +++ b/Frameworks/Account/LocalAccount/LocalAccountDelegate.swift @@ -202,4 +202,14 @@ final class LocalAccountDelegate: AccountDelegate { static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil, completion: (Result) -> Void) { return completion(.success(nil)) } + + // MARK: Suspend and Resume (for iOS) + + func suspend() { + // Nothing to do + } + + func resume() { + // Nothing to do + } } diff --git a/Frameworks/Account/ReaderAPI/ReaderAPIAccountDelegate.swift b/Frameworks/Account/ReaderAPI/ReaderAPIAccountDelegate.swift index 862a30a82..493a29e2c 100644 --- a/Frameworks/Account/ReaderAPI/ReaderAPIAccountDelegate.swift +++ b/Frameworks/Account/ReaderAPI/ReaderAPIAccountDelegate.swift @@ -436,7 +436,18 @@ final class ReaderAPIAccountDelegate: AccountDelegate { } } - + + // MARK: Suspend and Resume (for iOS) + + /// Suspend the sync database so that it can close its SQLite file. + func suspend() { + database.suspend() + } + + /// Resume the sync database — let it reopen its SQLite file. + func resume() { + database.resume() + } } // MARK: Private