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:
parent
1cfc4532d7
commit
6c781f3a63
@ -364,31 +364,42 @@ public final class AccountManager: UnreadCountProvider {
|
|||||||
return articles
|
return articles
|
||||||
}
|
}
|
||||||
|
|
||||||
public func fetchArticlesAsync(_ fetchType: FetchType, _ completion: @escaping ArticleSetResultBlock) {
|
public func fetchArticlesAsync(_ fetchType: FetchType, _ completion: @escaping ArticleSetResultBlock) {
|
||||||
precondition(Thread.isMainThread)
|
precondition(Thread.isMainThread)
|
||||||
|
|
||||||
var allFetchedArticles = Set<Article>()
|
var allFetchedArticles = Set<Article>()
|
||||||
let numberOfAccounts = activeAccounts.count
|
let numberOfAccounts = activeAccounts.count
|
||||||
var accountsReporting = 0
|
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 {
|
guard numberOfAccounts > 0 else {
|
||||||
completion(.success(allFetchedArticles))
|
callCompletion(.success(allFetchedArticles))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for account in activeAccounts {
|
for account in activeAccounts {
|
||||||
account.fetchArticlesAsync(fetchType) { (articleSetResult) in
|
account.fetchArticlesAsync(fetchType) { (articleSetResult) in
|
||||||
|
precondition(Thread.isMainThread)
|
||||||
accountsReporting += 1
|
accountsReporting += 1
|
||||||
|
|
||||||
switch articleSetResult {
|
switch articleSetResult {
|
||||||
case .success(let articles):
|
case .success(let articles):
|
||||||
allFetchedArticles.formUnion(articles)
|
allFetchedArticles.formUnion(articles)
|
||||||
if accountsReporting == numberOfAccounts {
|
if accountsReporting == numberOfAccounts && !databaseFetchDidFail {
|
||||||
completion(.success(allFetchedArticles))
|
callCompletion(.success(allFetchedArticles))
|
||||||
}
|
}
|
||||||
case .failure(let databaseError):
|
case .failure(let databaseError):
|
||||||
completion(.failure(databaseError))
|
databaseFetchDidFail = true
|
||||||
return
|
callCompletion(.failure(databaseError))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user