Add Feed Provider refreshes to Local Account.

This commit is contained in:
Maurice Parker 2020-04-17 05:32:52 -05:00
parent a31db7e024
commit 95f1f64aa7
1 changed files with 48 additions and 15 deletions

View File

@ -7,6 +7,7 @@
// //
import Foundation import Foundation
import os.log
import RSCore import RSCore
import RSParser import RSParser
import Articles import Articles
@ -20,6 +21,8 @@ public enum LocalAccountDelegateError: String, Error {
final class LocalAccountDelegate: AccountDelegate { final class LocalAccountDelegate: AccountDelegate {
private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "LocalAccount")
weak var account: Account? weak var account: Account?
private lazy var refresher: LocalAccountRefresher? = { private lazy var refresher: LocalAccountRefresher? = {
@ -36,23 +39,54 @@ final class LocalAccountDelegate: AccountDelegate {
var accountMetadata: AccountMetadata? var accountMetadata: AccountMetadata?
let refreshProgress = DownloadProgress(numberOfTasks: 0) let refreshProgress = DownloadProgress(numberOfTasks: 0)
var refreshAllCompletion: ((Result<Void, Error>) -> Void)? = nil
func receiveRemoteNotification(for account: Account, userInfo: [AnyHashable : Any], completion: @escaping () -> Void) { func receiveRemoteNotification(for account: Account, userInfo: [AnyHashable : Any], completion: @escaping () -> Void) {
completion() completion()
} }
func refreshAll(for account: Account, completion: @escaping (Result<Void, Error>) -> Void) { func refreshAll(for account: Account, completion: @escaping (Result<Void, Error>) -> Void) {
guard refreshAllCompletion == nil else { guard refreshProgress.isComplete else {
completion(.success(())) completion(.success(()))
return return
} }
refreshAllCompletion = completion var refresherWebFeeds = Set<WebFeed>()
let webFeeds = account.flattenedWebFeeds() let webFeeds = account.flattenedWebFeeds()
refreshProgress.addToNumberOfTasksAndRemaining(webFeeds.count)
refresher?.refreshFeeds(webFeeds) let group = DispatchGroup()
for webFeed in webFeeds {
if let components = URLComponents(string: webFeed.url), let feedProvider = FeedProviderManager.shared.best(for: components, with: webFeed.username) {
refreshProgress.addToNumberOfTasksAndRemaining(1)
group.enter()
feedProvider.refresh(webFeed) { result in
switch result {
case .success(let parsedItems):
account.update(webFeed.webFeedID, with: parsedItems) { _ in
self.refreshProgress.completeTask()
group.leave()
}
case .failure(let error):
os_log(.error, log: self.log, "Feed Provider refresh error: %@.", error.localizedDescription)
self.refreshProgress.completeTask()
group.leave()
}
}
} else {
refresherWebFeeds.insert(webFeed)
}
}
refreshProgress.addToNumberOfTasksAndRemaining(refresherWebFeeds.count)
group.enter()
refresher?.refreshFeeds(refresherWebFeeds) {
group.leave()
}
group.notify(queue: DispatchQueue.main) {
completion(.success(()))
}
} }
func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) { func sendArticleStatus(for account: Account, completion: @escaping ((Result<Void, Error>) -> Void)) {
@ -176,19 +210,20 @@ final class LocalAccountDelegate: AccountDelegate {
} }
let feed = account.createWebFeed(with: nil, url: url.absoluteString, webFeedID: url.absoluteString, homePageURL: nil) let feed = account.createWebFeed(with: nil, url: url.absoluteString, webFeedID: url.absoluteString, homePageURL: nil)
container.addWebFeed(feed) feed.editedName = name
InitialFeedDownloader.download(url) { parsedFeed in InitialFeedDownloader.download(url) { parsedFeed in
self.refreshProgress.completeTask() self.refreshProgress.completeTask()
if let parsedFeed = parsedFeed { if let parsedFeed = parsedFeed {
account.update(feed, with: parsedFeed, {_ in}) account.update(feed, with: parsedFeed, {_ in
container.addWebFeed(feed)
completion(.success(feed))
})
} else {
completion(.failure(AccountError.createErrorNotFound))
} }
feed.editedName = name
completion(.success(feed))
} }
case .failure: case .failure:
@ -292,8 +327,6 @@ extension LocalAccountDelegate: LocalAccountRefresherDelegate {
func localAccountRefresherDidFinish(_ refresher: LocalAccountRefresher) { func localAccountRefresherDidFinish(_ refresher: LocalAccountRefresher) {
self.refreshProgress.clear() self.refreshProgress.clear()
account?.metadata.lastArticleFetchEndTime = Date() account?.metadata.lastArticleFetchEndTime = Date()
refreshAllCompletion?(.success(()))
refreshAllCompletion = nil
} }
} }