From f6a81c07fb0f23569dfce9c91e474e7be6a6dd71 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Thu, 23 Apr 2020 19:13:57 -0500 Subject: [PATCH] Implement article status deleting for Feed Providers --- Frameworks/Account/Account.swift | 6 +- .../CloudKit/CloudKitAccountDelegate.swift | 92 ++++++++++++++++--- .../LocalAccount/LocalAccountRefresher.swift | 8 +- 3 files changed, 89 insertions(+), 17 deletions(-) diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index 85257b9ed..66927d935 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -750,9 +750,9 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, database.update(with: parsedItems, webFeedID: webFeedID) { updateArticlesResult in switch updateArticlesResult { - case .success(let newAndUpdatedArticles): - self.sendNotificationAbout(newAndUpdatedArticles) - completion(.success(newAndUpdatedArticles)) + case .success(let articleChanges): + self.sendNotificationAbout(articleChanges) + completion(.success(articleChanges)) case .failure(let databaseError): completion(.failure(databaseError)) } diff --git a/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift b/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift index e64d0af88..42393d4bb 100644 --- a/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift +++ b/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift @@ -564,19 +564,40 @@ private extension CloudKitAccountDelegate { } func refreshWebFeeds(_ account: Account, _ webFeeds: Set, completion: @escaping () -> Void) { + + var newArticles = Set
() + var deletedArticles = Set
() + var refresherWebFeeds = Set() let group = DispatchGroup() + refreshProgress.addToNumberOfTasksAndRemaining(2) + for webFeed in webFeeds { if let components = URLComponents(string: webFeed.url), let feedProvider = FeedProviderManager.shared.best(for: components, with: webFeed.username) { 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() + + account.update(webFeed.webFeedID, with: parsedItems) { result in + switch result { + case .success(let articleChanges): + + newArticles.formUnion(articleChanges.newArticles ?? Set
()) + deletedArticles.formUnion(articleChanges.deletedArticles ?? Set
()) + + self.refreshProgress.completeTask() + group.leave() + + case .failure(let error): + os_log(.error, log: self.log, "Feed Provider refresh update error: %@.", error.localizedDescription) + self.refreshProgress.completeTask() + group.leave() + } + } + case .failure(let error): os_log(.error, log: self.log, "Feed Provider refresh error: %@.", error.localizedDescription) self.refreshProgress.completeTask() @@ -594,12 +615,21 @@ private extension CloudKitAccountDelegate { } group.notify(queue: DispatchQueue.main) { - completion() + + self.articlesZone.deleteArticles(deletedArticles) { _ in + self.refreshProgress.completeTask() + self.articlesZone.sendNewArticles(newArticles) { _ in + self.refreshProgress.completeTask() + completion() + } + } + } + } func createProviderWebFeed(for account: Account, urlComponents: URLComponents, editedName: String?, container: Container, feedProvider: FeedProvider, completion: @escaping (Result) -> Void) { - refreshProgress.addToNumberOfTasksAndRemaining(3) + refreshProgress.addToNumberOfTasksAndRemaining(5) feedProvider.assignName(urlComponents) { result in self.refreshProgress.completeTask() @@ -631,9 +661,28 @@ private extension CloudKitAccountDelegate { self.refreshProgress.completeTask() switch result { case .success(let parsedItems): - account.update(newURLString, with: parsedItems) { _ in - completion(.success(feed)) + + account.update(newURLString, with: parsedItems) { result in + switch result { + case .success(let articleChanges): + + let newArticles = articleChanges.newArticles ?? Set
() + let deletedArticles = articleChanges.deletedArticles ?? Set
() + + self.articlesZone.deleteArticles(deletedArticles) { _ in + self.refreshProgress.completeTask() + self.articlesZone.sendNewArticles(newArticles) { _ in + self.refreshProgress.completeTask() + completion(.success(feed)) + } + } + + case .failure(let error): + completion(.failure(error)) + } + } + case .failure: completion(.failure(AccountError.createErrorNotFound)) } @@ -654,7 +703,7 @@ private extension CloudKitAccountDelegate { func createRSSWebFeed(for account: Account, url: URL, editedName: String?, container: Container, completion: @escaping (Result) -> Void) { BatchUpdate.shared.start() - refreshProgress.addToNumberOfTasksAndRemaining(3) + refreshProgress.addToNumberOfTasksAndRemaining(5) FeedFinder.find(url: url) { result in self.refreshProgress.completeTask() @@ -689,10 +738,29 @@ private extension CloudKitAccountDelegate { self.refreshProgress.completeTask() if let parsedFeed = parsedFeed { - account.update(feed, with: parsedFeed, {_ in - BatchUpdate.shared.end() - completion(.success(feed)) - }) + account.update(feed, with: parsedFeed) { result in + switch result { + case .success(let articleChanges): + + BatchUpdate.shared.end() + let newArticles = articleChanges.newArticles ?? Set
() + let deletedArticles = articleChanges.deletedArticles ?? Set
() + + self.articlesZone.deleteArticles(deletedArticles) { _ in + self.refreshProgress.completeTask() + self.articlesZone.sendNewArticles(newArticles) { _ in + self.refreshProgress.completeTask() + completion(.success(feed)) + } + } + + case .failure(let error): + completion(.failure(error)) + } + + } + } else { + completion(.success(feed)) } } diff --git a/Frameworks/Account/LocalAccount/LocalAccountRefresher.swift b/Frameworks/Account/LocalAccount/LocalAccountRefresher.swift index 5695b809a..1d87496ba 100644 --- a/Frameworks/Account/LocalAccount/LocalAccountRefresher.swift +++ b/Frameworks/Account/LocalAccount/LocalAccountRefresher.swift @@ -30,6 +30,10 @@ final class LocalAccountRefresher { }() public func refreshFeeds(_ feeds: Set, completion: (() -> Void)? = nil) { + guard !feeds.isEmpty else { + completion?() + return + } if let completion = completion { completions.append(completion) } @@ -100,8 +104,8 @@ extension LocalAccountRefresher: DownloadSessionDelegate { } account.update(feed, with: parsedFeed) { result in - if case .success(let newAndUpdatedArticles) = result { - self.delegate?.localAccountRefresher(self, didProcess: newAndUpdatedArticles) { + if case .success(let articleChanges) = result { + self.delegate?.localAccountRefresher(self, didProcess: articleChanges) { if let httpResponse = response as? HTTPURLResponse { feed.conditionalGetInfo = HTTPConditionalGetInfo(urlResponse: httpResponse) }