diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index 953e59677..63f19149d 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -724,36 +724,56 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, completion(nil) return } - database.update(webFeedIDsAndItems: webFeedIDsAndItems, defaultRead: defaultRead) { updateArticlesResult in + + let group = DispatchGroup() + var possibleError: DatabaseError? = nil + var newArticles = Set
() + var updatedArticles = Set
() + + for (webFeedID, items) in webFeedIDsAndItems { + + group.enter() + database.update(webFeedID: webFeedID, items: items, defaultRead: defaultRead) { updateArticlesResult in - func process(_ newAndUpdatedArticles: NewAndUpdatedArticles) { - var userInfo = [String: Any]() - let webFeeds = Set(webFeedIDsAndItems.compactMap { (key, _) -> WebFeed? in - self.existingWebFeed(withWebFeedID: key) - }) - if let newArticles = newAndUpdatedArticles.newArticles, !newArticles.isEmpty { - self.updateUnreadCounts(for: webFeeds) { - NotificationCenter.default.post(name: .DownloadArticlesDidUpdateUnreadCounts, object: self, userInfo: nil) + switch updateArticlesResult { + case .success(let newAndUpdatedArticles): + if let articles = newAndUpdatedArticles.newArticles { + newArticles.formUnion(articles) } - userInfo[UserInfoKey.newArticles] = newArticles + if let articles = newAndUpdatedArticles.updatedArticles { + updatedArticles.formUnion(articles) + } + case .failure(let databaseError): + possibleError = databaseError } - if let updatedArticles = newAndUpdatedArticles.updatedArticles, !updatedArticles.isEmpty { - userInfo[UserInfoKey.updatedArticles] = updatedArticles - } - userInfo[UserInfoKey.webFeeds] = webFeeds - - completion(nil) - - NotificationCenter.default.post(name: .AccountDidDownloadArticles, object: self, userInfo: userInfo) - } - - switch updateArticlesResult { - case .success(let newAndUpdatedArticles): - process(newAndUpdatedArticles) - case .failure(let databaseError): - completion(databaseError) + + group.leave() } + } + + group.notify(queue: DispatchQueue.main) { + var userInfo = [String: Any]() + var webFeeds = Set(newArticles.compactMap { $0.webFeed }) + webFeeds.formUnion(Set(updatedArticles.compactMap { $0.webFeed })) + + if !newArticles.isEmpty { + self.updateUnreadCounts(for: webFeeds) { + NotificationCenter.default.post(name: .DownloadArticlesDidUpdateUnreadCounts, object: self, userInfo: nil) + } + userInfo[UserInfoKey.newArticles] = newArticles + } + + if !updatedArticles.isEmpty { + userInfo[UserInfoKey.updatedArticles] = updatedArticles + } + + userInfo[UserInfoKey.webFeeds] = webFeeds + NotificationCenter.default.post(name: .AccountDidDownloadArticles, object: self, userInfo: userInfo) + + completion(possibleError) + } + } @discardableResult diff --git a/Frameworks/ArticlesDatabase/ArticlesDatabase.swift b/Frameworks/ArticlesDatabase/ArticlesDatabase.swift index 3fca7e321..6f079f450 100644 --- a/Frameworks/ArticlesDatabase/ArticlesDatabase.swift +++ b/Frameworks/ArticlesDatabase/ArticlesDatabase.swift @@ -159,9 +159,9 @@ public final class ArticlesDatabase { // MARK: - Saving and Updating Articles - /// Update articles and save new ones. The key for ewbFeedIDsAndItems is webFeedID. - public func update(webFeedIDsAndItems: [String: Set], defaultRead: Bool, completion: @escaping UpdateArticlesCompletionBlock) { - articlesTable.update(webFeedIDsAndItems, defaultRead, completion) + /// Update articles and save new ones. + public func update(webFeedID: String, items: Set, defaultRead: Bool, completion: @escaping UpdateArticlesCompletionBlock) { + articlesTable.update(webFeedID, items, defaultRead, completion) } // MARK: - Status diff --git a/Frameworks/ArticlesDatabase/ArticlesTable.swift b/Frameworks/ArticlesDatabase/ArticlesTable.swift index 288aca756..4036650d1 100644 --- a/Frameworks/ArticlesDatabase/ArticlesTable.swift +++ b/Frameworks/ArticlesDatabase/ArticlesTable.swift @@ -169,8 +169,8 @@ final class ArticlesTable: DatabaseTable { // MARK: - Updating - func update(_ webFeedIDsAndItems: [String: Set], _ read: Bool, _ completion: @escaping UpdateArticlesCompletionBlock) { - if webFeedIDsAndItems.isEmpty { + func update(_ webFeedID: String, _ items: Set, _ read: Bool, _ completion: @escaping UpdateArticlesCompletionBlock) { + if items.isEmpty { callUpdateArticlesCompletionBlock(nil, nil, completion) return } @@ -184,18 +184,14 @@ final class ArticlesTable: DatabaseTable { // 7. Call back with new and updated Articles. // 8. Update search index. - var articleIDs = Set() - for (_, parsedItems) in webFeedIDsAndItems { - articleIDs.formUnion(parsedItems.articleIDs()) - } - self.queue.runInTransaction { (databaseResult) in func makeDatabaseCalls(_ database: FMDatabase) { + let articleIDs = items.articleIDs() let statusesDictionary = self.statusesTable.ensureStatusesForArticleIDs(articleIDs, read, database) //1 assert(statusesDictionary.count == articleIDs.count) - let allIncomingArticles = Article.articlesWithWebFeedIDsAndItems(webFeedIDsAndItems, self.accountID, statusesDictionary) //2 + let allIncomingArticles = Article.articlesWithWebFeedIDsAndItems(webFeedID, items, self.accountID, statusesDictionary) //2 if allIncomingArticles.isEmpty { self.callUpdateArticlesCompletionBlock(nil, nil, completion) return diff --git a/Frameworks/ArticlesDatabase/Extensions/Article+Database.swift b/Frameworks/ArticlesDatabase/Extensions/Article+Database.swift index 83c92822d..058922dfb 100644 --- a/Frameworks/ArticlesDatabase/Extensions/Article+Database.swift +++ b/Frameworks/ArticlesDatabase/Extensions/Article+Database.swift @@ -83,14 +83,10 @@ extension Article { // return Set(parsedItems.map{ Article(parsedItem: $0, maximumDateAllowed: maximumDateAllowed, accountID: accountID, feedID: feedID, status: statusesDictionary[$0.articleID]!) }) // } - static func articlesWithWebFeedIDsAndItems(_ webFeedIDsAndItems: [String: Set], _ accountID: String, _ statusesDictionary: [String: ArticleStatus]) -> Set
{ + static func articlesWithWebFeedIDsAndItems(_ webFeedID: String, _ items: Set, _ accountID: String, _ statusesDictionary: [String: ArticleStatus]) -> Set
{ let maximumDateAllowed = Date().addingTimeInterval(60 * 60 * 24) // Allow dates up to about 24 hours ahead of now - var articles = Set
() - for (webFeedID, parsedItems) in webFeedIDsAndItems { - let feedArticles = Set(parsedItems.map{ Article(parsedItem: $0, maximumDateAllowed: maximumDateAllowed, accountID: accountID, webFeedID: webFeedID, status: statusesDictionary[$0.articleID]!) }) - articles.formUnion(feedArticles) - } - return articles + let feedArticles = Set(items.map{ Article(parsedItem: $0, maximumDateAllowed: maximumDateAllowed, accountID: accountID, webFeedID: webFeedID, status: statusesDictionary[$0.articleID]!) }) + return feedArticles } }