Fix widget data encoding crash — and possibly other bugs — by making sure that fetchArticlesAsync calls its callback just once. (The widget data encoder was crashing with multiple calls in the failure case, since it ended up having unbalanced DispatchGroup enter and leave calls.)

This commit is contained in:
Brent Simmons 2023-01-21 14:49:08 -08:00
parent 06b4f9660b
commit 1e485f3e8d

View File

@ -370,25 +370,36 @@ public final class AccountManager: UnreadCountProvider {
var allFetchedArticles = Set<Article>()
let numberOfAccounts = activeAccounts.count
var accountsReporting = 0
var didCallCompletionBlock = false
var databaseFetchDidFail = false
func callCompletion(_ result: ArticleSetResult) {
guard !didCallCompletionBlock else {
return
}
completion(result)
didCallCompletionBlock = true
}
guard numberOfAccounts > 0 else {
completion(.success(allFetchedArticles))
callCompletion(.success(allFetchedArticles))
return
}
for account in activeAccounts {
account.fetchArticlesAsync(fetchType) { (articleSetResult) in
precondition(Thread.isMainThread)
accountsReporting += 1
switch articleSetResult {
case .success(let articles):
allFetchedArticles.formUnion(articles)
if accountsReporting == numberOfAccounts {
completion(.success(allFetchedArticles))
if accountsReporting == numberOfAccounts && !databaseFetchDidFail {
callCompletion(.success(allFetchedArticles))
}
case .failure(let databaseError):
completion(.failure(databaseError))
return
databaseFetchDidFail = true
callCompletion(.failure(databaseError))
}
}
}