From f0b8f927918fb44f863bf40708461febf95a62f0 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sun, 28 May 2023 22:26:46 -0700 Subject: [PATCH] Use cached logged-in account for things Fixes various race conditions with loading account Closes #251 --- Tusker/API/MastodonController.swift | 34 +++++++++---------- .../Onboarding/OnboardingViewController.swift | 2 +- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/Tusker/API/MastodonController.swift b/Tusker/API/MastodonController.swift index efbee1ac..a2c8174c 100644 --- a/Tusker/API/MastodonController.swift +++ b/Tusker/API/MastodonController.swift @@ -52,8 +52,7 @@ class MastodonController: ObservableObject { let client: Client! let instanceFeatures = InstanceFeatures() - @Published private(set) var accountID: String? - @Published private(set) var account: Account! + @Published private(set) var account: AccountMO? @Published private(set) var instance: Instance? @Published private(set) var instanceInfo: InstanceInfo! @Published private(set) var nodeInfo: NodeInfo! @@ -85,7 +84,7 @@ class MastodonController: ObservableObject { self.client.accessToken = accountInfo?.accessToken if !transient { - fetchActiveAccountID() + fetchActiveAccount() fetchActiveInstance() } @@ -234,8 +233,8 @@ class MastodonController: ObservableObject { } } - func getOwnAccount(completion: ((Result) -> Void)? = nil) { - if account != nil { + func getOwnAccount(completion: ((Result) -> Void)? = nil) { + if let account { completion?(.success(account)) } else { let request = Client.getSelfAccount() @@ -245,26 +244,25 @@ class MastodonController: ObservableObject { completion?(.failure(error)) case let .success(account, _): - DispatchQueue.main.async { - self.account = account - } - let context = self.persistentContainer.backgroundContext + let context = self.persistentContainer.viewContext context.perform { - if let accountMO = self.persistentContainer.account(for: account.id, in: context) { - accountMO.updateFrom(apiAccount: account, container: self.persistentContainer) - accountMO.active = true + let accountMO: AccountMO + if let existing = self.persistentContainer.account(for: account.id, in: context) { + accountMO = existing + existing.updateFrom(apiAccount: account, container: self.persistentContainer) } else { - let account = self.persistentContainer.addOrUpdateSynchronously(account: account, in: context) - account.active = true + accountMO = self.persistentContainer.addOrUpdateSynchronously(account: account, in: context) } - completion?(.success(account)) + accountMO.active = true + self.account = accountMO + completion?(.success(accountMO)) } } } } } - func getOwnAccount() async throws -> Account { + func getOwnAccount() async throws -> AccountMO { if let account = account { return account } else { @@ -375,11 +373,11 @@ class MastodonController: ObservableObject { } @MainActor - private func fetchActiveAccountID() { + private func fetchActiveAccount() { let req = AccountMO.fetchRequest() req.predicate = NSPredicate(format: "active = YES") if let activeAccount = try? persistentContainer.viewContext.fetch(req).first { - accountID = activeAccount.id + account = activeAccount } } diff --git a/Tusker/Screens/Onboarding/OnboardingViewController.swift b/Tusker/Screens/Onboarding/OnboardingViewController.swift index 402c783c..c3b6037b 100644 --- a/Tusker/Screens/Onboarding/OnboardingViewController.swift +++ b/Tusker/Screens/Onboarding/OnboardingViewController.swift @@ -150,7 +150,7 @@ class OnboardingViewController: UINavigationController { mastodonController.accountInfo = tempAccountInfo updateStatus("Checking Credentials") - let ownAccount: Account + let ownAccount: AccountMO do { ownAccount = try await retrying("Getting own account") { try await mastodonController.getOwnAccount()