diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index 63f19149d..d3b38278b 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -808,23 +808,23 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, } /// Mark articleIDs as read. Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification. - func markAsRead(_ articleIDs: Set) { - mark(articleIDs: articleIDs, statusKey: .read, flag: true) + func markAsRead(_ articleIDs: Set, completion: DatabaseCompletionBlock? = nil) { + mark(articleIDs: articleIDs, statusKey: .read, flag: true, completion: completion) } /// Mark articleIDs as unread. Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification. - func markAsUnread(_ articleIDs: Set) { - mark(articleIDs: articleIDs, statusKey: .read, flag: false) + func markAsUnread(_ articleIDs: Set, completion: DatabaseCompletionBlock? = nil) { + mark(articleIDs: articleIDs, statusKey: .read, flag: false, completion: completion) } /// Mark articleIDs as starred. Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification. - func markAsStarred(_ articleIDs: Set) { - mark(articleIDs: articleIDs, statusKey: .starred, flag: true) + func markAsStarred(_ articleIDs: Set, completion: DatabaseCompletionBlock? = nil) { + mark(articleIDs: articleIDs, statusKey: .starred, flag: true, completion: completion) } /// Mark articleIDs as unstarred. Will create statuses in the database and in memory as needed. Sends a .StatusesDidChange notification. - func markAsUnstarred(_ articleIDs: Set) { - mark(articleIDs: articleIDs, statusKey: .starred, flag: false) + func markAsUnstarred(_ articleIDs: Set, completion: DatabaseCompletionBlock? = nil) { + mark(articleIDs: articleIDs, statusKey: .starred, flag: false, completion: completion) } /// 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 c7713d6ff..e3b0623be 100644 --- a/Frameworks/Account/Feedly/Operations/FeedlySetStarredArticlesOperation.swift +++ b/Frameworks/Account/Feedly/Operations/FeedlySetStarredArticlesOperation.swift @@ -32,12 +32,13 @@ final class FeedlySetStarredArticlesOperation: FeedlyOperation { return } - account.fetchStarredArticleIDs { (articleIDsResult) in - if let localStarredArticleIDs = try? articleIDsResult.get() { + account.fetchStarredArticleIDs { result in + switch result { + case .success(let localStarredArticleIDs): self.processStarredArticleIDs(localStarredArticleIDs) - } - else { - self.didFinish() + + case .failure(let error): + self.didFinish(error) } } } @@ -50,15 +51,42 @@ private extension FeedlySetStarredArticlesOperation { didFinish() return } - - // Mark as starred + let remoteStarredArticleIDs = allStarredEntryIdsProvider.entryIds - account.mark(articleIDs: remoteStarredArticleIDs, statusKey: .starred, flag: true) + guard !remoteStarredArticleIDs.isEmpty else { + didFinish() + return + } + + let group = DispatchGroup() + + final class StarredStatusResults { + var markAsStarredError: Error? + var markAsUnstarredError: Error? + } + + let results = StarredStatusResults() + + group.enter() + account.markAsStarred(remoteStarredArticleIDs) { error in + results.markAsStarredError = error + group.leave() + } - // Mark as unstarred let deltaUnstarredArticleIDs = localStarredArticleIDs.subtracting(remoteStarredArticleIDs) - account.mark(articleIDs: deltaUnstarredArticleIDs, statusKey: .starred, flag: false) + group.enter() + account.markAsUnstarred(deltaUnstarredArticleIDs) { error in + results.markAsUnstarredError = error + group.leave() + } - didFinish() + group.notify(queue: .main) { + let markingError = results.markAsStarredError ?? results.markAsUnstarredError + guard let error = markingError else { + self.didFinish() + return + } + self.didFinish(error) + } } } diff --git a/Frameworks/Account/Feedly/Operations/FeedlySetUnreadArticlesOperation.swift b/Frameworks/Account/Feedly/Operations/FeedlySetUnreadArticlesOperation.swift index 6ec12bf4c..f98e93e81 100644 --- a/Frameworks/Account/Feedly/Operations/FeedlySetUnreadArticlesOperation.swift +++ b/Frameworks/Account/Feedly/Operations/FeedlySetUnreadArticlesOperation.swift @@ -32,12 +32,13 @@ final class FeedlySetUnreadArticlesOperation: FeedlyOperation { return } - account.fetchUnreadArticleIDs { articleIDsResult in - if let localUnreadArticleIDs = try? articleIDsResult.get() { + account.fetchUnreadArticleIDs { result in + switch result { + case .success(let localUnreadArticleIDs): self.processUnreadArticleIDs(localUnreadArticleIDs) - } - else { - self.didFinish() + + case .failure(let error): + self.didFinish(error) } } } @@ -52,11 +53,40 @@ private extension FeedlySetUnreadArticlesOperation { } let remoteUnreadArticleIDs = allUnreadIdsProvider.entryIds - account.markAsUnread(remoteUnreadArticleIDs) + guard !remoteUnreadArticleIDs.isEmpty else { + didFinish() + return + } + + let group = DispatchGroup() + + final class ReadStatusResults { + var markAsUnreadError: Error? + var markAsReadError: Error? + } + + let results = ReadStatusResults() + + group.enter() + account.markAsUnread(remoteUnreadArticleIDs) { error in + results.markAsUnreadError = error + group.leave() + } let articleIDsToMarkRead = localUnreadArticleIDs.subtracting(remoteUnreadArticleIDs) - account.markAsRead(articleIDsToMarkRead) + group.enter() + account.markAsRead(articleIDsToMarkRead) { error in + results.markAsReadError = error + group.leave() + } - didFinish() + group.notify(queue: .main) { + let markingError = results.markAsReadError ?? results.markAsUnreadError + guard let error = markingError else { + self.didFinish() + return + } + self.didFinish(error) + } } } diff --git a/Frameworks/Account/Feedly/Operations/FeedlySyncAllOperation.swift b/Frameworks/Account/Feedly/Operations/FeedlySyncAllOperation.swift index 9b58de533..595ad0555 100644 --- a/Frameworks/Account/Feedly/Operations/FeedlySyncAllOperation.swift +++ b/Frameworks/Account/Feedly/Operations/FeedlySyncAllOperation.swift @@ -70,6 +70,7 @@ final class FeedlySyncAllOperation: FeedlyOperation { // Get each and every starred article. let syncStarred = FeedlySyncStarredArticlesOperation(account: account, credentials: credentials, service: getStarredArticlesService, log: log) + syncStarred.delegate = self syncStarred.downloadProgress = downloadProgress syncStarred.addDependency(createFeedsOperation) self.operationQueue.addOperation(syncStarred) diff --git a/Frameworks/Account/Feedly/Operations/FeedlyUpdateAccountFeedsWithItemsOperation.swift b/Frameworks/Account/Feedly/Operations/FeedlyUpdateAccountFeedsWithItemsOperation.swift index a9465d349..b9820981e 100644 --- a/Frameworks/Account/Feedly/Operations/FeedlyUpdateAccountFeedsWithItemsOperation.swift +++ b/Frameworks/Account/Feedly/Operations/FeedlyUpdateAccountFeedsWithItemsOperation.swift @@ -31,7 +31,12 @@ final class FeedlyUpdateAccountFeedsWithItemsOperation: FeedlyOperation { let webFeedIDsAndItems = organisedItemsProvider.parsedItemsKeyedByFeedId - account.update(webFeedIDsAndItems: webFeedIDsAndItems, defaultRead: true) { _ in + account.update(webFeedIDsAndItems: webFeedIDsAndItems, defaultRead: true) { databaseError in + if let error = databaseError { + self.didFinish(error) + return + } + os_log(.debug, log: self.log, "Updated %i feeds for \"%@\"", webFeedIDsAndItems.count, self.organisedItemsProvider.providerName) self.didFinish() }