Ensures refresh tokens occurs before syncing. Implements cancelAll for Feedly.
This commit is contained in:
parent
6bef313937
commit
4c9e98c150
|
@ -15,6 +15,8 @@ import os.log
|
||||||
|
|
||||||
final class FeedlyAccountDelegate: AccountDelegate {
|
final class FeedlyAccountDelegate: AccountDelegate {
|
||||||
|
|
||||||
|
/// Feedly has a sandbox API and a production API.
|
||||||
|
/// This property is referred to when clients need to know which environment it should be pointing to.
|
||||||
static var environment: FeedlyAPICaller.API {
|
static var environment: FeedlyAPICaller.API {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
// https://developer.feedly.com/v3/developer/
|
// https://developer.feedly.com/v3/developer/
|
||||||
|
@ -61,11 +63,18 @@ final class FeedlyAccountDelegate: AccountDelegate {
|
||||||
private let database: SyncDatabase
|
private let database: SyncDatabase
|
||||||
|
|
||||||
private weak var currentSyncAllOperation: FeedlySyncAllOperation?
|
private weak var currentSyncAllOperation: FeedlySyncAllOperation?
|
||||||
|
private let operationQueue: OperationQueue
|
||||||
|
|
||||||
init(dataFolder: String, transport: Transport?, api: FeedlyAPICaller.API) {
|
init(dataFolder: String, transport: Transport?, api: FeedlyAPICaller.API) {
|
||||||
|
self.operationQueue = OperationQueue()
|
||||||
|
// Many operations have their own operation queues, such as the sync all operation.
|
||||||
|
// Making this a serial queue at this higher level of abstraction means we can ensure,
|
||||||
|
// for example, a `FeedlyRefreshAccessTokenOperation` occurs before a `FeedlySyncAllOperation`,
|
||||||
|
// improving our ability to debug, reason about and predict the behaviour of the code.
|
||||||
|
self.operationQueue.maxConcurrentOperationCount = 1
|
||||||
|
|
||||||
if let transport = transport {
|
if let transport = transport {
|
||||||
caller = FeedlyAPICaller(transport: transport, api: api)
|
self.caller = FeedlyAPICaller(transport: transport, api: api)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -83,7 +92,7 @@ final class FeedlyAccountDelegate: AccountDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
let session = URLSession(configuration: sessionConfiguration)
|
let session = URLSession(configuration: sessionConfiguration)
|
||||||
caller = FeedlyAPICaller(transport: session, api: api)
|
self.caller = FeedlyAPICaller(transport: session, api: api)
|
||||||
}
|
}
|
||||||
|
|
||||||
let databaseFilePath = (dataFolder as NSString).appendingPathComponent("Sync.sqlite3")
|
let databaseFilePath = (dataFolder as NSString).appendingPathComponent("Sync.sqlite3")
|
||||||
|
@ -93,7 +102,7 @@ final class FeedlyAccountDelegate: AccountDelegate {
|
||||||
// MARK: Account API
|
// MARK: Account API
|
||||||
|
|
||||||
func cancelAll(for account: Account) {
|
func cancelAll(for account: Account) {
|
||||||
// TODO: Implement me please
|
operationQueue.cancelAllOperations()
|
||||||
}
|
}
|
||||||
|
|
||||||
func refreshAll(for account: Account, completion: @escaping (Result<Void, Error>) -> Void) {
|
func refreshAll(for account: Account, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
@ -128,7 +137,7 @@ final class FeedlyAccountDelegate: AccountDelegate {
|
||||||
|
|
||||||
currentSyncAllOperation = operation
|
currentSyncAllOperation = operation
|
||||||
|
|
||||||
OperationQueue.main.addOperation(operation)
|
operationQueue.addOperation(operation)
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
|
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
|
||||||
|
@ -139,7 +148,7 @@ final class FeedlyAccountDelegate: AccountDelegate {
|
||||||
completion(.success(()))
|
completion(.success(()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OperationQueue.main.addOperation(send)
|
operationQueue.addOperation(send)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to ensure local articles have the same status as they do remotely.
|
/// Attempts to ensure local articles have the same status as they do remotely.
|
||||||
|
@ -159,18 +168,18 @@ final class FeedlyAccountDelegate: AccountDelegate {
|
||||||
|
|
||||||
let group = DispatchGroup()
|
let group = DispatchGroup()
|
||||||
|
|
||||||
let getUnread = FeedlySyncUnreadStatusesOperation(account: account, credentials: credentials, service: caller, newerThan: nil, log: log)
|
let syncUnread = FeedlySyncUnreadStatusesOperation(account: account, credentials: credentials, service: caller, newerThan: nil, log: log)
|
||||||
|
|
||||||
group.enter()
|
group.enter()
|
||||||
getUnread.completionBlock = {
|
syncUnread.completionBlock = {
|
||||||
group.leave()
|
group.leave()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let getStarred = FeedlySyncStarredArticlesOperation(account: account, credentials: credentials, service: caller, log: log)
|
let syncStarred = FeedlySyncStarredArticlesOperation(account: account, credentials: credentials, service: caller, log: log)
|
||||||
|
|
||||||
group.enter()
|
group.enter()
|
||||||
getStarred.completionBlock = {
|
syncStarred.completionBlock = {
|
||||||
group.leave()
|
group.leave()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +187,7 @@ final class FeedlyAccountDelegate: AccountDelegate {
|
||||||
completion(.success(()))
|
completion(.success(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
OperationQueue.main.addOperations([getUnread, getStarred], waitUntilFinished: false)
|
operationQueue.addOperations([syncUnread, syncStarred], waitUntilFinished: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func importOPML(for account: Account, opmlFile: URL, completion: @escaping (Result<Void, Error>) -> Void) {
|
func importOPML(for account: Account, opmlFile: URL, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
@ -477,10 +486,11 @@ final class FeedlyAccountDelegate: AccountDelegate {
|
||||||
|
|
||||||
let client = FeedlyAccountDelegate.oauthAuthorizationClient
|
let client = FeedlyAccountDelegate.oauthAuthorizationClient
|
||||||
let refreshAccessToken = FeedlyRefreshAccessTokenOperation(account: account, service: self, oauthClient: client, log: log)
|
let refreshAccessToken = FeedlyRefreshAccessTokenOperation(account: account, service: self, oauthClient: client, log: log)
|
||||||
OperationQueue.main.addOperation(refreshAccessToken)
|
operationQueue.addOperation(refreshAccessToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, completion: @escaping (Result<Credentials?, Error>) -> Void) {
|
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, completion: @escaping (Result<Credentials?, Error>) -> Void) {
|
||||||
fatalError()
|
assertionFailure("An `account` instance should enqueue an \(FeedlyRefreshAccessTokenOperation.self) instead.")
|
||||||
|
completion(.success(credentials))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue