From 1e485f3e8dad591a0021f4164130f9cd31704713 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 21 Jan 2023 14:49:08 -0800 Subject: [PATCH] =?UTF-8?q?Fix=20widget=20data=20encoding=20crash=20?= =?UTF-8?q?=E2=80=94=C2=A0and=20possibly=20other=20bugs=20=E2=80=94=C2=A0b?= =?UTF-8?q?y=20making=20sure=20that=20`fetchArticlesAsync`=20calls=20its?= =?UTF-8?q?=20callback=20just=20once.=20(The=20widget=20data=20encoder=20w?= =?UTF-8?q?as=20crashing=20with=20multiple=20calls=20in=20the=20failure=20?= =?UTF-8?q?case,=20since=20it=20ended=20up=20having=20unbalanced=20Dispatc?= =?UTF-8?q?hGroup=20enter=20and=20leave=20calls.)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Account/Sources/Account/AccountManager.swift | 25 ++++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/Account/Sources/Account/AccountManager.swift b/Account/Sources/Account/AccountManager.swift index 07bd893d9..d267bc260 100644 --- a/Account/Sources/Account/AccountManager.swift +++ b/Account/Sources/Account/AccountManager.swift @@ -364,31 +364,42 @@ public final class AccountManager: UnreadCountProvider { return articles } - public func fetchArticlesAsync(_ fetchType: FetchType, _ completion: @escaping ArticleSetResultBlock) { + public func fetchArticlesAsync(_ fetchType: FetchType, _ completion: @escaping ArticleSetResultBlock) { precondition(Thread.isMainThread) var allFetchedArticles = Set
() 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)) } } }