diff --git a/Frameworks/Account/NewsBlur/NewsBlurAPICaller.swift b/Frameworks/Account/NewsBlur/NewsBlurAPICaller.swift index 9f51552bd..95c50f144 100644 --- a/Frameworks/Account/NewsBlur/NewsBlurAPICaller.swift +++ b/Frameworks/Account/NewsBlur/NewsBlurAPICaller.swift @@ -25,6 +25,7 @@ final class NewsBlurAPICaller: NSObject { private let baseURL = URL(string: "https://www.newsblur.com/")! private var transport: Transport! + private var suspended = false var credentials: Credentials? weak var accountMetadata: AccountMetadata? @@ -34,11 +35,26 @@ final class NewsBlurAPICaller: NSObject { self.transport = transport } + /// Cancels all pending requests rejects any that come in later + func suspend() { + transport.cancelAll() + suspended = true + } + + func resume() { + suspended = false + } + func validateCredentials(completion: @escaping (Result) -> Void) { let url = baseURL.appendingPathComponent("api/login") let request = URLRequest(url: url, credentials: credentials) transport.send(request: request, resultType: NewsBlurLoginResponse.self) { result in + if self.suspended { + completion(.failure(TransportError.suspended)) + return + } + switch result { case .success(let response, let payload): guard let url = response.url, let headerFields = response.allHeaderFields as? [String: String], payload?.code != -1 else { @@ -75,6 +91,11 @@ final class NewsBlurAPICaller: NSObject { let request = URLRequest(url: url, credentials: credentials) transport.send(request: request) { result in + if self.suspended { + completion(.failure(TransportError.suspended)) + return + } + switch result { case .success: completion(.success(())) @@ -99,6 +120,11 @@ final class NewsBlurAPICaller: NSObject { let request = URLRequest(url: callURL, credentials: credentials) transport.send(request: request, resultType: NewsBlurFeedsResponse.self) { result in + if self.suspended { + completion(.failure(TransportError.suspended)) + return + } + switch result { case .success((_, let payload)): completion(.success((payload?.feeds, payload?.folders))) @@ -122,6 +148,11 @@ final class NewsBlurAPICaller: NSObject { let request = URLRequest(url: callURL, credentials: credentials) transport.send(request: request, resultType: NewsBlurUnreadStoryHashesResponse.self, dateDecoding: .secondsSince1970) { result in + if self.suspended { + completion(.failure(TransportError.suspended)) + return + } + switch result { case .success((_, let payload)): completion(.success(payload?.feeds.values.flatMap { $0 })) @@ -144,6 +175,11 @@ final class NewsBlurAPICaller: NSObject { let request = URLRequest(url: callURL, credentials: credentials) transport.send(request: request, resultType: NewsBlurStoriesResponse.self) { result in + if self.suspended { + completion(.failure(TransportError.suspended)) + return + } + switch result { case .success((_, let payload)): completion(.success(payload?.stories)) diff --git a/Frameworks/Account/NewsBlur/NewsBlurAccountDelegate.swift b/Frameworks/Account/NewsBlur/NewsBlurAccountDelegate.swift index 37a2c252d..8c565209e 100644 --- a/Frameworks/Account/NewsBlur/NewsBlurAccountDelegate.swift +++ b/Frameworks/Account/NewsBlur/NewsBlurAccountDelegate.swift @@ -213,14 +213,21 @@ final class NewsBlurAccountDelegate: AccountDelegate { } } + // MARK: Suspend and Resume (for iOS) + + /// Suspend all network activity func suspendNetwork() { + caller.suspend() } + /// Suspend the SQLLite databases func suspendDatabase() { database.suspend() } + /// Make sure no SQLite databases are open and we are ready to issue network requests. func resume() { + caller.resume() database.resume() } }