Use cached logged-in account for things

Fixes various race conditions with loading account

Closes #251
This commit is contained in:
Shadowfacts 2023-05-28 22:26:46 -07:00
parent da88303a22
commit f0b8f92791
2 changed files with 17 additions and 19 deletions

View File

@ -52,8 +52,7 @@ class MastodonController: ObservableObject {
let client: Client! let client: Client!
let instanceFeatures = InstanceFeatures() let instanceFeatures = InstanceFeatures()
@Published private(set) var accountID: String? @Published private(set) var account: AccountMO?
@Published private(set) var account: Account!
@Published private(set) var instance: Instance? @Published private(set) var instance: Instance?
@Published private(set) var instanceInfo: InstanceInfo! @Published private(set) var instanceInfo: InstanceInfo!
@Published private(set) var nodeInfo: NodeInfo! @Published private(set) var nodeInfo: NodeInfo!
@ -85,7 +84,7 @@ class MastodonController: ObservableObject {
self.client.accessToken = accountInfo?.accessToken self.client.accessToken = accountInfo?.accessToken
if !transient { if !transient {
fetchActiveAccountID() fetchActiveAccount()
fetchActiveInstance() fetchActiveInstance()
} }
@ -234,8 +233,8 @@ class MastodonController: ObservableObject {
} }
} }
func getOwnAccount(completion: ((Result<Account, Client.Error>) -> Void)? = nil) { func getOwnAccount(completion: ((Result<AccountMO, Client.Error>) -> Void)? = nil) {
if account != nil { if let account {
completion?(.success(account)) completion?(.success(account))
} else { } else {
let request = Client.getSelfAccount() let request = Client.getSelfAccount()
@ -245,26 +244,25 @@ class MastodonController: ObservableObject {
completion?(.failure(error)) completion?(.failure(error))
case let .success(account, _): case let .success(account, _):
DispatchQueue.main.async { let context = self.persistentContainer.viewContext
self.account = account
}
let context = self.persistentContainer.backgroundContext
context.perform { context.perform {
if let accountMO = self.persistentContainer.account(for: account.id, in: context) { let accountMO: AccountMO
accountMO.updateFrom(apiAccount: account, container: self.persistentContainer) if let existing = self.persistentContainer.account(for: account.id, in: context) {
accountMO.active = true accountMO = existing
existing.updateFrom(apiAccount: account, container: self.persistentContainer)
} else { } else {
let account = self.persistentContainer.addOrUpdateSynchronously(account: account, in: context) accountMO = self.persistentContainer.addOrUpdateSynchronously(account: account, in: context)
account.active = true
} }
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 { if let account = account {
return account return account
} else { } else {
@ -375,11 +373,11 @@ class MastodonController: ObservableObject {
} }
@MainActor @MainActor
private func fetchActiveAccountID() { private func fetchActiveAccount() {
let req = AccountMO.fetchRequest() let req = AccountMO.fetchRequest()
req.predicate = NSPredicate(format: "active = YES") req.predicate = NSPredicate(format: "active = YES")
if let activeAccount = try? persistentContainer.viewContext.fetch(req).first { if let activeAccount = try? persistentContainer.viewContext.fetch(req).first {
accountID = activeAccount.id account = activeAccount
} }
} }

View File

@ -150,7 +150,7 @@ class OnboardingViewController: UINavigationController {
mastodonController.accountInfo = tempAccountInfo mastodonController.accountInfo = tempAccountInfo
updateStatus("Checking Credentials") updateStatus("Checking Credentials")
let ownAccount: Account let ownAccount: AccountMO
do { do {
ownAccount = try await retrying("Getting own account") { ownAccount = try await retrying("Getting own account") {
try await mastodonController.getOwnAccount() try await mastodonController.getOwnAccount()