Change to make sure all queue's get cleared before suspending the database. Issue #1389
This commit is contained in:
parent
77cf9a0036
commit
f159371967
|
@ -406,7 +406,6 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
|
||||||
}
|
}
|
||||||
|
|
||||||
public func suspend() {
|
public func suspend() {
|
||||||
delegate.cancelAll(for: self)
|
|
||||||
delegate.suspend()
|
delegate.suspend()
|
||||||
database.suspend()
|
database.suspend()
|
||||||
save()
|
save()
|
||||||
|
|
|
@ -22,7 +22,6 @@ protocol AccountDelegate {
|
||||||
|
|
||||||
var refreshProgress: DownloadProgress { get }
|
var refreshProgress: DownloadProgress { get }
|
||||||
|
|
||||||
func cancelAll(for account: Account)
|
|
||||||
func refreshAll(for account: Account, completion: @escaping (Result<Void, Error>) -> Void)
|
func refreshAll(for account: Account, completion: @escaping (Result<Void, Error>) -> Void)
|
||||||
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void))
|
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void))
|
||||||
func refreshArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void))
|
func refreshArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void))
|
||||||
|
|
|
@ -32,6 +32,7 @@ final class FeedbinAPICaller: NSObject {
|
||||||
|
|
||||||
private let feedbinBaseURL = URL(string: "https://api.feedbin.com/v2/")!
|
private let feedbinBaseURL = URL(string: "https://api.feedbin.com/v2/")!
|
||||||
private var transport: Transport!
|
private var transport: Transport!
|
||||||
|
private var suspended = false
|
||||||
|
|
||||||
var credentials: Credentials?
|
var credentials: Credentials?
|
||||||
weak var accountMetadata: AccountMetadata?
|
weak var accountMetadata: AccountMetadata?
|
||||||
|
@ -41,8 +42,14 @@ final class FeedbinAPICaller: NSObject {
|
||||||
self.transport = transport
|
self.transport = transport
|
||||||
}
|
}
|
||||||
|
|
||||||
func cancelAll() {
|
/// Cancels all pending requests rejects any that come in later
|
||||||
|
func suspend() {
|
||||||
transport.cancelAll()
|
transport.cancelAll()
|
||||||
|
suspended = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func resume() {
|
||||||
|
suspended = false
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateCredentials(completion: @escaping (Result<Credentials?, Error>) -> Void) {
|
func validateCredentials(completion: @escaping (Result<Credentials?, Error>) -> Void) {
|
||||||
|
@ -51,6 +58,12 @@ final class FeedbinAPICaller: NSObject {
|
||||||
let request = URLRequest(url: callURL, credentials: credentials)
|
let request = URLRequest(url: callURL, credentials: credentials)
|
||||||
|
|
||||||
transport.send(request: request) { result in
|
transport.send(request: request) { result in
|
||||||
|
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
case .success:
|
case .success:
|
||||||
completion(.success(self.credentials))
|
completion(.success(self.credentials))
|
||||||
|
@ -78,6 +91,11 @@ final class FeedbinAPICaller: NSObject {
|
||||||
|
|
||||||
transport.send(request: request, method: HTTPMethod.post, payload: opmlData) { result in
|
transport.send(request: request, method: HTTPMethod.post, payload: opmlData) { result in
|
||||||
|
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let (_, data)):
|
case .success(let (_, data)):
|
||||||
|
|
||||||
|
@ -108,6 +126,11 @@ final class FeedbinAPICaller: NSObject {
|
||||||
|
|
||||||
transport.send(request: request, resultType: FeedbinImportResult.self) { result in
|
transport.send(request: request, resultType: FeedbinImportResult.self) { result in
|
||||||
|
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let (_, importResult)):
|
case .success(let (_, importResult)):
|
||||||
completion(.success(importResult))
|
completion(.success(importResult))
|
||||||
|
@ -127,6 +150,11 @@ final class FeedbinAPICaller: NSObject {
|
||||||
|
|
||||||
transport.send(request: request, resultType: [FeedbinTag].self) { result in
|
transport.send(request: request, resultType: [FeedbinTag].self) { result in
|
||||||
|
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let (response, tags)):
|
case .success(let (response, tags)):
|
||||||
self.storeConditionalGet(key: ConditionalGetKeys.tags, headers: response.allHeaderFields)
|
self.storeConditionalGet(key: ConditionalGetKeys.tags, headers: response.allHeaderFields)
|
||||||
|
@ -143,7 +171,20 @@ final class FeedbinAPICaller: NSObject {
|
||||||
let callURL = feedbinBaseURL.appendingPathComponent("tags.json")
|
let callURL = feedbinBaseURL.appendingPathComponent("tags.json")
|
||||||
let request = URLRequest(url: callURL, credentials: credentials)
|
let request = URLRequest(url: callURL, credentials: credentials)
|
||||||
let payload = FeedbinRenameTag(oldName: oldName, newName: newName)
|
let payload = FeedbinRenameTag(oldName: oldName, newName: newName)
|
||||||
transport.send(request: request, method: HTTPMethod.post, payload: payload, completion: completion)
|
|
||||||
|
transport.send(request: request, method: HTTPMethod.post, payload: payload) { result in
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
|
completion(.success(()))
|
||||||
|
case .failure(let error):
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func retrieveSubscriptions(completion: @escaping (Result<[FeedbinSubscription]?, Error>) -> Void) {
|
func retrieveSubscriptions(completion: @escaping (Result<[FeedbinSubscription]?, Error>) -> Void) {
|
||||||
|
@ -156,6 +197,11 @@ final class FeedbinAPICaller: NSObject {
|
||||||
|
|
||||||
transport.send(request: request, resultType: [FeedbinSubscription].self) { result in
|
transport.send(request: request, resultType: [FeedbinSubscription].self) { result in
|
||||||
|
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let (response, subscriptions)):
|
case .success(let (response, subscriptions)):
|
||||||
self.storeConditionalGet(key: ConditionalGetKeys.subscriptions, headers: response.allHeaderFields)
|
self.storeConditionalGet(key: ConditionalGetKeys.subscriptions, headers: response.allHeaderFields)
|
||||||
|
@ -186,6 +232,11 @@ final class FeedbinAPICaller: NSObject {
|
||||||
|
|
||||||
transport.send(request: request, method: HTTPMethod.post, payload: payload) { result in
|
transport.send(request: request, method: HTTPMethod.post, payload: payload) { result in
|
||||||
|
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let (response, data)):
|
case .success(let (response, data)):
|
||||||
|
|
||||||
|
@ -246,13 +297,38 @@ final class FeedbinAPICaller: NSObject {
|
||||||
let callURL = feedbinBaseURL.appendingPathComponent("subscriptions/\(subscriptionID)/update.json")
|
let callURL = feedbinBaseURL.appendingPathComponent("subscriptions/\(subscriptionID)/update.json")
|
||||||
let request = URLRequest(url: callURL, credentials: credentials)
|
let request = URLRequest(url: callURL, credentials: credentials)
|
||||||
let payload = FeedbinUpdateSubscription(title: newName)
|
let payload = FeedbinUpdateSubscription(title: newName)
|
||||||
transport.send(request: request, method: HTTPMethod.post, payload: payload, completion: completion)
|
|
||||||
|
transport.send(request: request, method: HTTPMethod.post, payload: payload) { result in
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
|
completion(.success(()))
|
||||||
|
case .failure(let error):
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteSubscription(subscriptionID: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
func deleteSubscription(subscriptionID: String, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
let callURL = feedbinBaseURL.appendingPathComponent("subscriptions/\(subscriptionID).json")
|
let callURL = feedbinBaseURL.appendingPathComponent("subscriptions/\(subscriptionID).json")
|
||||||
let request = URLRequest(url: callURL, credentials: credentials)
|
let request = URLRequest(url: callURL, credentials: credentials)
|
||||||
transport.send(request: request, method: HTTPMethod.delete, completion: completion)
|
transport.send(request: request, method: HTTPMethod.delete) { result in
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
|
completion(.success(()))
|
||||||
|
case .failure(let error):
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func retrieveTaggings(completion: @escaping (Result<[FeedbinTagging]?, Error>) -> Void) {
|
func retrieveTaggings(completion: @escaping (Result<[FeedbinTagging]?, Error>) -> Void) {
|
||||||
|
@ -262,7 +338,11 @@ final class FeedbinAPICaller: NSObject {
|
||||||
let request = URLRequest(url: callURL, credentials: credentials, conditionalGet: conditionalGet)
|
let request = URLRequest(url: callURL, credentials: credentials, conditionalGet: conditionalGet)
|
||||||
|
|
||||||
transport.send(request: request, resultType: [FeedbinTagging].self) { result in
|
transport.send(request: request, resultType: [FeedbinTagging].self) { result in
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let (response, taggings)):
|
case .success(let (response, taggings)):
|
||||||
self.storeConditionalGet(key: ConditionalGetKeys.taggings, headers: response.allHeaderFields)
|
self.storeConditionalGet(key: ConditionalGetKeys.taggings, headers: response.allHeaderFields)
|
||||||
|
@ -291,6 +371,11 @@ final class FeedbinAPICaller: NSObject {
|
||||||
|
|
||||||
transport.send(request: request, method: HTTPMethod.post, payload:payload) { result in
|
transport.send(request: request, method: HTTPMethod.post, payload:payload) { result in
|
||||||
|
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let (response, _)):
|
case .success(let (response, _)):
|
||||||
if let taggingLocation = response.valueForHTTPHeaderField(HTTPResponseHeader.location),
|
if let taggingLocation = response.valueForHTTPHeaderField(HTTPResponseHeader.location),
|
||||||
|
@ -313,7 +398,19 @@ final class FeedbinAPICaller: NSObject {
|
||||||
let callURL = feedbinBaseURL.appendingPathComponent("taggings/\(taggingID).json")
|
let callURL = feedbinBaseURL.appendingPathComponent("taggings/\(taggingID).json")
|
||||||
var request = URLRequest(url: callURL, credentials: credentials)
|
var request = URLRequest(url: callURL, credentials: credentials)
|
||||||
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: HTTPRequestHeader.contentType)
|
request.addValue("application/json; charset=utf-8", forHTTPHeaderField: HTTPRequestHeader.contentType)
|
||||||
transport.send(request: request, method: HTTPMethod.delete, completion: completion)
|
transport.send(request: request, method: HTTPMethod.delete) { result in
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
|
completion(.success(()))
|
||||||
|
case .failure(let error):
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func retrieveEntries(articleIDs: [String], completion: @escaping (Result<([FeedbinEntry]?), Error>) -> Void) {
|
func retrieveEntries(articleIDs: [String], completion: @escaping (Result<([FeedbinEntry]?), Error>) -> Void) {
|
||||||
|
@ -336,6 +433,11 @@ final class FeedbinAPICaller: NSObject {
|
||||||
|
|
||||||
transport.send(request: request, resultType: [FeedbinEntry].self) { result in
|
transport.send(request: request, resultType: [FeedbinEntry].self) { result in
|
||||||
|
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let (_, entries)):
|
case .success(let (_, entries)):
|
||||||
completion(.success((entries)))
|
completion(.success((entries)))
|
||||||
|
@ -363,6 +465,11 @@ final class FeedbinAPICaller: NSObject {
|
||||||
|
|
||||||
transport.send(request: request, resultType: [FeedbinEntry].self) { result in
|
transport.send(request: request, resultType: [FeedbinEntry].self) { result in
|
||||||
|
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let (response, entries)):
|
case .success(let (response, entries)):
|
||||||
|
|
||||||
|
@ -399,6 +506,11 @@ final class FeedbinAPICaller: NSObject {
|
||||||
|
|
||||||
transport.send(request: request, resultType: [FeedbinEntry].self) { result in
|
transport.send(request: request, resultType: [FeedbinEntry].self) { result in
|
||||||
|
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let (response, entries)):
|
case .success(let (response, entries)):
|
||||||
|
|
||||||
|
@ -427,6 +539,11 @@ final class FeedbinAPICaller: NSObject {
|
||||||
|
|
||||||
transport.send(request: request, resultType: [FeedbinEntry].self) { result in
|
transport.send(request: request, resultType: [FeedbinEntry].self) { result in
|
||||||
|
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let (response, entries)):
|
case .success(let (response, entries)):
|
||||||
|
|
||||||
|
@ -449,6 +566,11 @@ final class FeedbinAPICaller: NSObject {
|
||||||
|
|
||||||
transport.send(request: request, resultType: [Int].self) { result in
|
transport.send(request: request, resultType: [Int].self) { result in
|
||||||
|
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let (response, unreadEntries)):
|
case .success(let (response, unreadEntries)):
|
||||||
self.storeConditionalGet(key: ConditionalGetKeys.unreadEntries, headers: response.allHeaderFields)
|
self.storeConditionalGet(key: ConditionalGetKeys.unreadEntries, headers: response.allHeaderFields)
|
||||||
|
@ -465,14 +587,38 @@ final class FeedbinAPICaller: NSObject {
|
||||||
let callURL = feedbinBaseURL.appendingPathComponent("unread_entries.json")
|
let callURL = feedbinBaseURL.appendingPathComponent("unread_entries.json")
|
||||||
let request = URLRequest(url: callURL, credentials: credentials)
|
let request = URLRequest(url: callURL, credentials: credentials)
|
||||||
let payload = FeedbinUnreadEntry(unreadEntries: entries)
|
let payload = FeedbinUnreadEntry(unreadEntries: entries)
|
||||||
transport.send(request: request, method: HTTPMethod.post, payload: payload, completion: completion)
|
transport.send(request: request, method: HTTPMethod.post, payload: payload) { result in
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
|
completion(.success(()))
|
||||||
|
case .failure(let error):
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteUnreadEntries(entries: [Int], completion: @escaping (Result<Void, Error>) -> Void) {
|
func deleteUnreadEntries(entries: [Int], completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
let callURL = feedbinBaseURL.appendingPathComponent("unread_entries.json")
|
let callURL = feedbinBaseURL.appendingPathComponent("unread_entries.json")
|
||||||
let request = URLRequest(url: callURL, credentials: credentials)
|
let request = URLRequest(url: callURL, credentials: credentials)
|
||||||
let payload = FeedbinUnreadEntry(unreadEntries: entries)
|
let payload = FeedbinUnreadEntry(unreadEntries: entries)
|
||||||
transport.send(request: request, method: HTTPMethod.delete, payload: payload, completion: completion)
|
transport.send(request: request, method: HTTPMethod.delete, payload: payload) { result in
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
|
completion(.success(()))
|
||||||
|
case .failure(let error):
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func retrieveStarredEntries(completion: @escaping (Result<[Int]?, Error>) -> Void) {
|
func retrieveStarredEntries(completion: @escaping (Result<[Int]?, Error>) -> Void) {
|
||||||
|
@ -482,7 +628,11 @@ final class FeedbinAPICaller: NSObject {
|
||||||
let request = URLRequest(url: callURL, credentials: credentials, conditionalGet: conditionalGet)
|
let request = URLRequest(url: callURL, credentials: credentials, conditionalGet: conditionalGet)
|
||||||
|
|
||||||
transport.send(request: request, resultType: [Int].self) { result in
|
transport.send(request: request, resultType: [Int].self) { result in
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let (response, starredEntries)):
|
case .success(let (response, starredEntries)):
|
||||||
self.storeConditionalGet(key: ConditionalGetKeys.starredEntries, headers: response.allHeaderFields)
|
self.storeConditionalGet(key: ConditionalGetKeys.starredEntries, headers: response.allHeaderFields)
|
||||||
|
@ -499,14 +649,38 @@ final class FeedbinAPICaller: NSObject {
|
||||||
let callURL = feedbinBaseURL.appendingPathComponent("starred_entries.json")
|
let callURL = feedbinBaseURL.appendingPathComponent("starred_entries.json")
|
||||||
let request = URLRequest(url: callURL, credentials: credentials)
|
let request = URLRequest(url: callURL, credentials: credentials)
|
||||||
let payload = FeedbinStarredEntry(starredEntries: entries)
|
let payload = FeedbinStarredEntry(starredEntries: entries)
|
||||||
transport.send(request: request, method: HTTPMethod.post, payload: payload, completion: completion)
|
transport.send(request: request, method: HTTPMethod.post, payload: payload) { result in
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
|
completion(.success(()))
|
||||||
|
case .failure(let error):
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteStarredEntries(entries: [Int], completion: @escaping (Result<Void, Error>) -> Void) {
|
func deleteStarredEntries(entries: [Int], completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
let callURL = feedbinBaseURL.appendingPathComponent("starred_entries.json")
|
let callURL = feedbinBaseURL.appendingPathComponent("starred_entries.json")
|
||||||
let request = URLRequest(url: callURL, credentials: credentials)
|
let request = URLRequest(url: callURL, credentials: credentials)
|
||||||
let payload = FeedbinStarredEntry(starredEntries: entries)
|
let payload = FeedbinStarredEntry(starredEntries: entries)
|
||||||
transport.send(request: request, method: HTTPMethod.delete, payload: payload, completion: completion)
|
transport.send(request: request, method: HTTPMethod.delete, payload: payload) { result in
|
||||||
|
if self.suspended {
|
||||||
|
completion(.failure(TransportError.suspended))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch result {
|
||||||
|
case .success:
|
||||||
|
completion(.success(()))
|
||||||
|
case .failure(let error):
|
||||||
|
completion(.failure(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,10 +73,6 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
||||||
|
|
||||||
var refreshProgress = DownloadProgress(numberOfTasks: 0)
|
var refreshProgress = DownloadProgress(numberOfTasks: 0)
|
||||||
|
|
||||||
func cancelAll(for account: Account) {
|
|
||||||
caller.cancelAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
func refreshAll(for account: Account, completion: @escaping (Result<Void, Error>) -> Void) {
|
func refreshAll(for account: Account, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
|
||||||
refreshProgress.addToNumberOfTasksAndRemaining(5)
|
refreshProgress.addToNumberOfTasksAndRemaining(5)
|
||||||
|
@ -560,11 +556,13 @@ final class FeedbinAccountDelegate: AccountDelegate {
|
||||||
|
|
||||||
/// Suspend the sync database so that it can close its SQLite file.
|
/// Suspend the sync database so that it can close its SQLite file.
|
||||||
func suspend() {
|
func suspend() {
|
||||||
|
caller.suspend()
|
||||||
database.suspend()
|
database.suspend()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resume the sync database — let it reopen its SQLite file.
|
/// Resume the sync database — let it reopen its SQLite file.
|
||||||
func resume() {
|
func resume() {
|
||||||
|
caller.resume()
|
||||||
database.resume()
|
database.resume()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,10 +97,6 @@ final class FeedlyAccountDelegate: AccountDelegate {
|
||||||
|
|
||||||
// MARK: Account API
|
// MARK: Account API
|
||||||
|
|
||||||
func cancelAll(for account: Account) {
|
|
||||||
operationQueue.cancelAllOperations()
|
|
||||||
}
|
|
||||||
|
|
||||||
func refreshAll(for account: Account, completion: @escaping (Result<Void, Error>) -> Void) {
|
func refreshAll(for account: Account, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
assert(Thread.isMainThread)
|
assert(Thread.isMainThread)
|
||||||
|
|
||||||
|
@ -515,6 +511,7 @@ final class FeedlyAccountDelegate: AccountDelegate {
|
||||||
|
|
||||||
/// Suspend the sync database so that it can close its SQLite file.
|
/// Suspend the sync database so that it can close its SQLite file.
|
||||||
func suspend() {
|
func suspend() {
|
||||||
|
operationQueue.cancelAllOperations()
|
||||||
database.suspend()
|
database.suspend()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,10 +79,6 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
|
||||||
|
|
||||||
var refreshProgress = DownloadProgress(numberOfTasks: 0)
|
var refreshProgress = DownloadProgress(numberOfTasks: 0)
|
||||||
|
|
||||||
func cancelAll(for account: Account) {
|
|
||||||
caller.cancelAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
func refreshAll(for account: Account, completion: @escaping (Result<Void, Error>) -> Void) {
|
func refreshAll(for account: Account, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
|
||||||
refreshProgress.addToNumberOfTasksAndRemaining(6)
|
refreshProgress.addToNumberOfTasksAndRemaining(6)
|
||||||
|
@ -441,6 +437,7 @@ final class ReaderAPIAccountDelegate: AccountDelegate {
|
||||||
|
|
||||||
/// Suspend the sync database so that it can close its SQLite file.
|
/// Suspend the sync database so that it can close its SQLite file.
|
||||||
func suspend() {
|
func suspend() {
|
||||||
|
caller.cancelAll()
|
||||||
database.suspend()
|
database.suspend()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,12 +46,6 @@ final class FetchRequestOperation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The account manager may have been suspended while we were queued up
|
|
||||||
if AccountManager.shared.isSuspended {
|
|
||||||
callCompletionIfNeeded()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if isCanceled {
|
if isCanceled {
|
||||||
callCompletionIfNeeded()
|
callCompletionIfNeeded()
|
||||||
return
|
return
|
||||||
|
|
|
@ -229,6 +229,7 @@ private extension AppDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Go To Background
|
// MARK: Go To Background
|
||||||
|
|
||||||
private extension AppDelegate {
|
private extension AppDelegate {
|
||||||
|
|
||||||
func waitForSyncTasksToFinish() {
|
func waitForSyncTasksToFinish() {
|
||||||
|
@ -269,7 +270,7 @@ private extension AppDelegate {
|
||||||
|
|
||||||
func completeProcessing(_ suspend: Bool) {
|
func completeProcessing(_ suspend: Bool) {
|
||||||
if suspend {
|
if suspend {
|
||||||
AccountManager.shared.suspendAll()
|
suspendApplication()
|
||||||
}
|
}
|
||||||
UIApplication.shared.endBackgroundTask(self.waitBackgroundUpdateTask)
|
UIApplication.shared.endBackgroundTask(self.waitBackgroundUpdateTask)
|
||||||
self.waitBackgroundUpdateTask = UIBackgroundTaskIdentifier.invalid
|
self.waitBackgroundUpdateTask = UIBackgroundTaskIdentifier.invalid
|
||||||
|
@ -299,6 +300,16 @@ private extension AppDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func suspendApplication() {
|
||||||
|
CoalescingQueue.standard.performCallsImmediately()
|
||||||
|
for scene in UIApplication.shared.connectedScenes {
|
||||||
|
if let sceneDelegate = scene.delegate as? SceneDelegate {
|
||||||
|
sceneDelegate.suspend()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AccountManager.shared.suspendAll()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Background Tasks
|
// MARK: Background Tasks
|
||||||
|
@ -342,9 +353,9 @@ private extension AppDelegate {
|
||||||
if AccountManager.shared.isSuspended {
|
if AccountManager.shared.isSuspended {
|
||||||
AccountManager.shared.resumeAll()
|
AccountManager.shared.resumeAll()
|
||||||
}
|
}
|
||||||
AccountManager.shared.refreshAll(errorHandler: ErrorHandler.log) {
|
AccountManager.shared.refreshAll(errorHandler: ErrorHandler.log) { [unowned self] in
|
||||||
AccountManager.shared.saveAll()
|
AccountManager.shared.saveAll()
|
||||||
AccountManager.shared.suspendAll()
|
self.suspendApplication()
|
||||||
os_log("Account refresh operation completed.", log: self.log, type: .info)
|
os_log("Account refresh operation completed.", log: self.log, type: .info)
|
||||||
task?.setTaskCompleted(success: true)
|
task?.setTaskCompleted(success: true)
|
||||||
}
|
}
|
||||||
|
|
|
@ -535,6 +535,11 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
|
||||||
|
|
||||||
// MARK: API
|
// MARK: API
|
||||||
|
|
||||||
|
func suspend() {
|
||||||
|
fetchAndMergeArticlesQueue.performCallsImmediately()
|
||||||
|
fetchRequestQueue.cancelAllRequests()
|
||||||
|
}
|
||||||
|
|
||||||
func shadowNodesFor(section: Int) -> [Node] {
|
func shadowNodesFor(section: Int) -> [Node] {
|
||||||
return shadowTable[section]
|
return shadowTable[section]
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,10 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||||
coordinator.handle(response)
|
coordinator.handle(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func suspend() {
|
||||||
|
coordinator.suspend()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension SceneDelegate {
|
private extension SceneDelegate {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit b2ef3e111339ba9dd9070ed0ded8e053135559cb
|
Subproject commit 0631696e7383368664a1fe47c58ebcd0ee2d49f8
|
Loading…
Reference in New Issue