From 6ec11119f8333b1dc7ee194809987d77993c5133 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Fri, 10 Apr 2020 18:10:54 -0500 Subject: [PATCH] Add external web feed to status so that it can prompt receiving system to pull down new articles. --- .../CloudKit/CloudKitAccountDelegate.swift | 12 +++--- .../CloudKit/CloudKitArticlesZone.swift | 26 ++++++++++--- .../CloudKitArticlesZoneDelegate.swift | 37 ++++++++++--------- 3 files changed, 46 insertions(+), 29 deletions(-) diff --git a/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift b/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift index d20e23e30..b35dfb543 100644 --- a/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift +++ b/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift @@ -98,12 +98,12 @@ final class CloudKitAccountDelegate: AccountDelegate { return } - let starredArticleIDs = syncStatuses.filter({ $0.key == .starred && $0.flag == true }).map({ $0.articleID }) - account.fetchArticlesAsync(.articleIDs(Set(starredArticleIDs))) { result in + let articleIDs = syncStatuses.map({ $0.articleID }) + account.fetchArticlesAsync(.articleIDs(Set(articleIDs))) { result in - func processWithArticles(_ starredArticles: Set
) { + func processWithArticles(_ articles: Set
) { - self.articlesZone.sendArticleStatus(syncStatuses, starredArticles: starredArticles) { result in + self.articlesZone.sendArticleStatus(syncStatuses, articles: articles) { result in switch result { case .success: self.database.deleteSelectedForProcessing(syncStatuses.map({ $0.articleID }) ) @@ -119,8 +119,8 @@ final class CloudKitAccountDelegate: AccountDelegate { } switch result { - case .success(let starredArticles): - processWithArticles(starredArticles) + case .success(let articles): + processWithArticles(articles) case .failure(let databaseError): completion(.failure(databaseError)) } diff --git a/Frameworks/Account/CloudKit/CloudKitArticlesZone.swift b/Frameworks/Account/CloudKit/CloudKitArticlesZone.swift index 8a11fd951..02c84d78f 100644 --- a/Frameworks/Account/CloudKit/CloudKitArticlesZone.swift +++ b/Frameworks/Account/CloudKit/CloudKitArticlesZone.swift @@ -48,6 +48,7 @@ final class CloudKitArticlesZone: CloudKitZone { struct CloudKitArticleStatus { static let recordType = "ArticleStatus" struct Fields { + static let webFeedExternalID = "webFeedExternalID" static let read = "read" static let starred = "starred" static let userDeleted = "userDeleted" @@ -81,8 +82,11 @@ final class CloudKitArticlesZone: CloudKitZone { } } - func sendArticleStatus(_ syncStatuses: [SyncStatus], starredArticles: Set
, completion: @escaping ((Result) -> Void)) { - var records = makeStatusRecords(syncStatuses) + func sendArticleStatus(_ syncStatuses: [SyncStatus], articles: Set
, completion: @escaping ((Result) -> Void)) { + + var records = makeStatusRecords(syncStatuses, articles) + + let starredArticles = articles.filter({ $0.status.starred == true }) makeArticleRecordsIfNecessary(starredArticles) { result in switch result { case .success(let articleRecords): @@ -92,11 +96,11 @@ final class CloudKitArticlesZone: CloudKitZone { case .success: completion(.success(())) case .failure(let error): - self.handleSendArticleStatusError(error, syncStatuses: syncStatuses, starredArticles: starredArticles, completion: completion) + self.handleSendArticleStatusError(error, syncStatuses: syncStatuses, starredArticles: articles, completion: completion) } } case .failure(let error): - self.handleSendArticleStatusError(error, syncStatuses: syncStatuses, starredArticles: starredArticles, completion: completion) + self.handleSendArticleStatusError(error, syncStatuses: syncStatuses, starredArticles: articles, completion: completion) } } } @@ -106,7 +110,7 @@ final class CloudKitArticlesZone: CloudKitZone { self.createZoneRecord() { result in switch result { case .success: - self.sendArticleStatus(syncStatuses, starredArticles: starredArticles, completion: completion) + self.sendArticleStatus(syncStatuses, articles: starredArticles, completion: completion) case .failure(let error): completion(.failure(error)) } @@ -120,7 +124,13 @@ final class CloudKitArticlesZone: CloudKitZone { private extension CloudKitArticlesZone { - func makeStatusRecords(_ syncStatuses: [SyncStatus]) -> [CKRecord] { + func makeStatusRecords(_ syncStatuses: [SyncStatus], _ articles: Set
) -> [CKRecord] { + + var articleDict = [String: Article]() + for article in articles { + articleDict[article.articleID] = article + } + var records = [String: CKRecord]() for status in syncStatuses { @@ -132,6 +142,10 @@ private extension CloudKitArticlesZone { records[status.articleID] = record } + if let webFeedExternalID = articleDict[status.articleID]?.webFeed?.externalID { + record![CloudKitArticleStatus.Fields.webFeedExternalID] = webFeedExternalID + } + switch status.key { case .read: record![CloudKitArticleStatus.Fields.read] = status.flag ? "1" : "0" diff --git a/Frameworks/Account/CloudKit/CloudKitArticlesZoneDelegate.swift b/Frameworks/Account/CloudKit/CloudKitArticlesZoneDelegate.swift index 58469ebb2..b33e73b9d 100644 --- a/Frameworks/Account/CloudKit/CloudKitArticlesZoneDelegate.swift +++ b/Frameworks/Account/CloudKit/CloudKitArticlesZoneDelegate.swift @@ -94,25 +94,28 @@ private extension CloudKitArticlesZoneDelegate { if newArticleStatusIDs.isEmpty { group.leave() } else { - self.account?.fetchArticlesAsync(FetchType.articleIDs(newArticleStatusIDs)) { result in - switch result { - case .success(let articles): - - if articles.isEmpty { - group.leave() - } else { - let webFeeds = Set(articles.compactMap({ $0.webFeed })) - webFeeds.forEach { $0.dropConditionalGetInfo() } - self.refreshProgress?.addToNumberOfTasksAndRemaining(webFeeds.count) - self.refresher?.refreshFeeds(webFeeds) { - group.leave() - } - } - - case .failure: - group.leave() + + var webFeedExternalIDDict = [String: String]() + for record in records { + if let webFeedExternalID = record[CloudKitArticlesZone.CloudKitArticleStatus.Fields.webFeedExternalID] as? String { + webFeedExternalIDDict[record.externalID] = webFeedExternalID } } + + var webFeeds = Set() + for newArticleStatusID in newArticleStatusIDs { + if let webFeedExternalID = webFeedExternalIDDict[newArticleStatusID], + let webFeed = self.account?.existingWebFeed(withExternalID: webFeedExternalID) { + webFeeds.insert(webFeed) + } + } + + webFeeds.forEach { $0.dropConditionalGetInfo() } + self.refreshProgress?.addToNumberOfTasksAndRemaining(webFeeds.count) + self.refresher?.refreshFeeds(webFeeds) { + group.leave() + } + } case .failure: