Ensures Feedly status operations finish at the right time. In part, this is achieved by adding and using completion handlers to the asynchronous ensure status API.

This commit is contained in:
Kiel Gillard 2019-11-06 13:20:48 +11:00
parent bed5cfa94d
commit 434b11ed17
5 changed files with 39 additions and 11 deletions

View File

@ -687,10 +687,12 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
return updatedArticles return updatedArticles
} }
func ensureStatuses(_ articleIDs: Set<String>, _ defaultRead: Bool, _ statusKey: ArticleStatus.Key, _ flag: Bool) { func ensureStatuses(_ articleIDs: Set<String>, _ defaultRead: Bool, _ statusKey: ArticleStatus.Key, _ flag: Bool, completionHandler: (() -> ())? = nil) {
if !articleIDs.isEmpty { guard !articleIDs.isEmpty else {
database.ensureStatuses(articleIDs, defaultRead, statusKey, flag) 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. /// Empty caches that can reasonably be emptied. Call when the app goes in the background, for instance.

View File

@ -32,6 +32,8 @@ final class FeedlySetStarredArticlesOperation: FeedlyOperation {
return return
} }
let group = DispatchGroup()
let remoteStarredArticleIds = allStarredEntryIdsProvider.entryIds let remoteStarredArticleIds = allStarredEntryIdsProvider.entryIds
let localStarredArticleIDs = account.fetchStarredArticleIDs() let localStarredArticleIDs = account.fetchStarredArticleIDs()
@ -43,7 +45,10 @@ final class FeedlySetStarredArticlesOperation: FeedlyOperation {
// Save any starred statuses for articles we haven't yet received // Save any starred statuses for articles we haven't yet received
let markStarredArticleIDs = Set(markStarredArticles.map { $0.articleID }) let markStarredArticleIDs = Set(markStarredArticles.map { $0.articleID })
let missingStarredArticleIDs = deltaStarredArticleIDs.subtracting(markStarredArticleIDs) 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 // Mark articles as unstarred
let deltaUnstarredArticleIDs = localStarredArticleIDs.subtracting(remoteStarredArticleIds) let deltaUnstarredArticleIDs = localStarredArticleIDs.subtracting(remoteStarredArticleIds)
@ -53,6 +58,13 @@ final class FeedlySetStarredArticlesOperation: FeedlyOperation {
// Save any unstarred statuses for articles we haven't yet received // Save any unstarred statuses for articles we haven't yet received
let markUnstarredArticleIDs = Set(markUnstarredArticles.map { $0.articleID }) let markUnstarredArticleIDs = Set(markUnstarredArticles.map { $0.articleID })
let missingUnstarredArticleIDs = deltaUnstarredArticleIDs.subtracting(markUnstarredArticleIDs) 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()
}
} }
} }

View File

@ -32,6 +32,8 @@ final class FeedlySetUnreadArticlesOperation: FeedlyOperation {
return return
} }
let group = DispatchGroup()
let remoteUnreadArticleIds = allUnreadIdsProvider.entryIds let remoteUnreadArticleIds = allUnreadIdsProvider.entryIds
//Set(entries.filter { $0.unread }.map { $0.id }) //Set(entries.filter { $0.unread }.map { $0.id })
let localUnreadArticleIds = account.fetchUnreadArticleIDs() let localUnreadArticleIds = account.fetchUnreadArticleIDs()
@ -44,7 +46,11 @@ final class FeedlySetUnreadArticlesOperation: FeedlyOperation {
// Save any unread statuses for articles we haven't yet received // Save any unread statuses for articles we haven't yet received
let markUnreadArticleIDs = Set(markUnreadArticles.map { $0.articleID }) let markUnreadArticleIDs = Set(markUnreadArticles.map { $0.articleID })
let missingUnreadArticleIDs = deltaUnreadArticleIds.subtracting(markUnreadArticleIDs) 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 // Mark articles as read
let deltaReadArticleIds = localUnreadArticleIds.subtracting(remoteUnreadArticleIds) let deltaReadArticleIds = localUnreadArticleIds.subtracting(remoteUnreadArticleIds)
@ -54,8 +60,13 @@ final class FeedlySetUnreadArticlesOperation: FeedlyOperation {
// Save any read statuses for articles we haven't yet received // Save any read statuses for articles we haven't yet received
let markReadArticleIDs = Set(markReadArticles.map { $0.articleID }) let markReadArticleIDs = Set(markReadArticles.map { $0.articleID })
let missingReadArticleIDs = deltaReadArticleIds.subtracting(markReadArticleIDs) 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()
}
} }
} }

View File

@ -131,8 +131,8 @@ public final class ArticlesDatabase {
articlesTable.update(feedIDsAndItems, defaultRead, completion) articlesTable.update(feedIDsAndItems, defaultRead, completion)
} }
public func ensureStatuses(_ articleIDs: Set<String>, _ defaultRead: Bool, _ statusKey: ArticleStatus.Key, _ flag: Bool) { public func ensureStatuses(_ articleIDs: Set<String>, _ defaultRead: Bool, _ statusKey: ArticleStatus.Key, _ flag: Bool, completionHandler: (() -> ())? = nil) {
articlesTable.ensureStatuses(articleIDs, defaultRead, statusKey, flag) articlesTable.ensureStatuses(articleIDs, defaultRead, statusKey, flag, completionHandler: completionHandler)
} }
// MARK: - Status // MARK: - Status

View File

@ -279,11 +279,14 @@ final class ArticlesTable: DatabaseTable {
} }
} }
func ensureStatuses(_ articleIDs: Set<String>, _ defaultRead: Bool, _ statusKey: ArticleStatus.Key, _ flag: Bool) { func ensureStatuses(_ articleIDs: Set<String>, _ defaultRead: Bool, _ statusKey: ArticleStatus.Key, _ flag: Bool, completionHandler: (() -> ())? = nil) {
self.queue.update { (database) in self.queue.update { (database) in
let statusesDictionary = self.statusesTable.ensureStatusesForArticleIDs(articleIDs, defaultRead, database) let statusesDictionary = self.statusesTable.ensureStatusesForArticleIDs(articleIDs, defaultRead, database)
let statuses = Set(statusesDictionary.values) let statuses = Set(statusesDictionary.values)
self.statusesTable.mark(statuses, statusKey, flag, database) self.statusesTable.mark(statuses, statusKey, flag, database)
if let handler = completionHandler {
DispatchQueue.main.async(execute: handler)
}
} }
} }