diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index 4866c329a..fa49bd0e6 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -687,10 +687,12 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, return updatedArticles } - func ensureStatuses(_ articleIDs: Set, _ defaultRead: Bool, _ statusKey: ArticleStatus.Key, _ flag: Bool) { - if !articleIDs.isEmpty { - database.ensureStatuses(articleIDs, defaultRead, statusKey, flag) + func ensureStatuses(_ articleIDs: Set, _ defaultRead: Bool, _ statusKey: ArticleStatus.Key, _ flag: Bool, completionHandler: (() -> ())? = nil) { + guard !articleIDs.isEmpty else { + completionHandler?() + return } + database.ensureStatuses(articleIDs, defaultRead, statusKey, flag, completionHandler: completionHandler) } /// Empty caches that can reasonably be emptied. Call when the app goes in the background, for instance. diff --git a/Frameworks/Account/Feedly/Operations/FeedlySetStarredArticlesOperation.swift b/Frameworks/Account/Feedly/Operations/FeedlySetStarredArticlesOperation.swift index 9814ae3e8..ebd11bd87 100644 --- a/Frameworks/Account/Feedly/Operations/FeedlySetStarredArticlesOperation.swift +++ b/Frameworks/Account/Feedly/Operations/FeedlySetStarredArticlesOperation.swift @@ -32,6 +32,8 @@ final class FeedlySetStarredArticlesOperation: FeedlyOperation { return } + let group = DispatchGroup() + let remoteStarredArticleIds = allStarredEntryIdsProvider.entryIds let localStarredArticleIDs = account.fetchStarredArticleIDs() @@ -43,7 +45,10 @@ final class FeedlySetStarredArticlesOperation: FeedlyOperation { // Save any starred statuses for articles we haven't yet received let markStarredArticleIDs = Set(markStarredArticles.map { $0.articleID }) let missingStarredArticleIDs = deltaStarredArticleIDs.subtracting(markStarredArticleIDs) - account.ensureStatuses(missingStarredArticleIDs, true, .starred, true) + group.enter() + account.ensureStatuses(missingStarredArticleIDs, true, .starred, true) { + group.leave() + } // Mark articles as unstarred let deltaUnstarredArticleIDs = localStarredArticleIDs.subtracting(remoteStarredArticleIds) @@ -53,6 +58,13 @@ final class FeedlySetStarredArticlesOperation: FeedlyOperation { // Save any unstarred statuses for articles we haven't yet received let markUnstarredArticleIDs = Set(markUnstarredArticles.map { $0.articleID }) let missingUnstarredArticleIDs = deltaUnstarredArticleIDs.subtracting(markUnstarredArticleIDs) - account.ensureStatuses(missingUnstarredArticleIDs, true, .starred, false) + group.enter() + account.ensureStatuses(missingUnstarredArticleIDs, true, .starred, false) { + group.leave() + } + + group.notify(queue: .main) { + self.didFinish() + } } } diff --git a/Frameworks/Account/Feedly/Operations/FeedlySetUnreadArticlesOperation.swift b/Frameworks/Account/Feedly/Operations/FeedlySetUnreadArticlesOperation.swift index 4ba6059f8..e48cac533 100644 --- a/Frameworks/Account/Feedly/Operations/FeedlySetUnreadArticlesOperation.swift +++ b/Frameworks/Account/Feedly/Operations/FeedlySetUnreadArticlesOperation.swift @@ -32,6 +32,8 @@ final class FeedlySetUnreadArticlesOperation: FeedlyOperation { return } + let group = DispatchGroup() + let remoteUnreadArticleIds = allUnreadIdsProvider.entryIds //Set(entries.filter { $0.unread }.map { $0.id }) let localUnreadArticleIds = account.fetchUnreadArticleIDs() @@ -44,7 +46,11 @@ final class FeedlySetUnreadArticlesOperation: FeedlyOperation { // Save any unread statuses for articles we haven't yet received let markUnreadArticleIDs = Set(markUnreadArticles.map { $0.articleID }) let missingUnreadArticleIDs = deltaUnreadArticleIds.subtracting(markUnreadArticleIDs) - account.ensureStatuses(missingUnreadArticleIDs, true, .read, false) + + group.enter() + account.ensureStatuses(missingUnreadArticleIDs, true, .read, false) { + group.leave() + } // Mark articles as read let deltaReadArticleIds = localUnreadArticleIds.subtracting(remoteUnreadArticleIds) @@ -54,8 +60,13 @@ final class FeedlySetUnreadArticlesOperation: FeedlyOperation { // Save any read statuses for articles we haven't yet received let markReadArticleIDs = Set(markReadArticles.map { $0.articleID }) let missingReadArticleIDs = deltaReadArticleIds.subtracting(markReadArticleIDs) - account.ensureStatuses(missingReadArticleIDs, true, .read, true) + group.enter() + account.ensureStatuses(missingReadArticleIDs, true, .read, true) { + group.leave() + } - didFinish() + group.notify(queue: .main) { + self.didFinish() + } } } diff --git a/Frameworks/ArticlesDatabase/ArticlesDatabase.swift b/Frameworks/ArticlesDatabase/ArticlesDatabase.swift index 0c7111fa1..2c4bc08d1 100644 --- a/Frameworks/ArticlesDatabase/ArticlesDatabase.swift +++ b/Frameworks/ArticlesDatabase/ArticlesDatabase.swift @@ -131,8 +131,8 @@ public final class ArticlesDatabase { articlesTable.update(feedIDsAndItems, defaultRead, completion) } - public func ensureStatuses(_ articleIDs: Set, _ defaultRead: Bool, _ statusKey: ArticleStatus.Key, _ flag: Bool) { - articlesTable.ensureStatuses(articleIDs, defaultRead, statusKey, flag) + public func ensureStatuses(_ articleIDs: Set, _ defaultRead: Bool, _ statusKey: ArticleStatus.Key, _ flag: Bool, completionHandler: (() -> ())? = nil) { + articlesTable.ensureStatuses(articleIDs, defaultRead, statusKey, flag, completionHandler: completionHandler) } // MARK: - Status diff --git a/Frameworks/ArticlesDatabase/ArticlesTable.swift b/Frameworks/ArticlesDatabase/ArticlesTable.swift index c2553dffc..e0b924a05 100644 --- a/Frameworks/ArticlesDatabase/ArticlesTable.swift +++ b/Frameworks/ArticlesDatabase/ArticlesTable.swift @@ -279,11 +279,14 @@ final class ArticlesTable: DatabaseTable { } } - func ensureStatuses(_ articleIDs: Set, _ defaultRead: Bool, _ statusKey: ArticleStatus.Key, _ flag: Bool) { + func ensureStatuses(_ articleIDs: Set, _ defaultRead: Bool, _ statusKey: ArticleStatus.Key, _ flag: Bool, completionHandler: (() -> ())? = nil) { self.queue.update { (database) in let statusesDictionary = self.statusesTable.ensureStatusesForArticleIDs(articleIDs, defaultRead, database) let statuses = Set(statusesDictionary.values) self.statusesTable.mark(statuses, statusKey, flag, database) + if let handler = completionHandler { + DispatchQueue.main.async(execute: handler) + } } }