Fix crash opening Preferences with deleted accounts

This commit is contained in:
Shadowfacts 2020-09-16 17:52:00 -04:00
parent 99db842411
commit 9d9ea565f1
Signed by untrusted user: shadowfacts
GPG Key ID: 94A5AB95422746E5
4 changed files with 36 additions and 20 deletions

View File

@ -84,23 +84,28 @@ class MastodonController {
}
}
func getOwnAccount(completion: ((Account) -> Void)? = nil) {
func getOwnAccount(completion: ((Result<Account, Client.Error>) -> Void)? = nil) {
if account != nil {
completion?(account)
completion?(.success(account))
} else {
let request = Client.getSelfAccount()
run(request) { response in
guard case let .success(account, _) = response else { fatalError() }
self.account = account
self.persistentContainer.backgroundContext.perform {
if let accountMO = self.persistentContainer.account(for: account.id, in: self.persistentContainer.backgroundContext) {
accountMO.updateFrom(apiAccount: account, container: self.persistentContainer)
} else {
// the first time the user's account is added to the store,
// increment its reference count so that it's never removed
self.persistentContainer.addOrUpdate(account: account, incrementReferenceCount: true)
switch response {
case let .failure(error):
completion?(.failure(error))
case let .success(account, _):
self.account = account
self.persistentContainer.backgroundContext.perform {
if let accountMO = self.persistentContainer.account(for: account.id, in: self.persistentContainer.backgroundContext) {
accountMO.updateFrom(apiAccount: account, container: self.persistentContainer)
} else {
// the first time the user's account is added to the store,
// increment its reference count so that it's never removed
self.persistentContainer.addOrUpdate(account: account, incrementReferenceCount: true)
}
completion?(.success(account))
}
completion?(account)
}
}
}

View File

@ -70,13 +70,21 @@ extension OnboardingViewController: InstanceSelectorTableViewControllerDelegate
let tempAccountInfo = LocalData.UserAccountInfo(id: "temp", instanceURL: instanceURL, clientID: clientID, clientSecret: clientSecret, username: nil, accessToken: accessToken)
mastodonController.accountInfo = tempAccountInfo
mastodonController.getOwnAccount { (account) in
mastodonController.getOwnAccount { (result) in
DispatchQueue.main.async {
// this needs to happen on the main thread because it publishes a new value for the ObservableObject
let accountInfo = LocalData.shared.addAccount(instanceURL: instanceURL, clientID: clientID, clientSecret: clientSecret, username: account.username, accessToken: accessToken)
mastodonController.accountInfo = accountInfo
self.onboardingDelegate?.didFinishOnboarding(account: accountInfo)
switch result {
case let .failure(error):
let alert = UIAlertController(title: "Unable to Verify Credentials", message: "Your account could not be fetched at this time: \(error.localizedDescription)", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
self.present(alert, animated: true)
case let .success(account):
// this needs to happen on the main thread because it publishes a new value for the ObservableObject
let accountInfo = LocalData.shared.addAccount(instanceURL: instanceURL, clientID: clientID, clientSecret: clientSecret, username: account.username, accessToken: accessToken)
mastodonController.accountInfo = accountInfo
self.onboardingDelegate?.didFinishOnboarding(account: accountInfo)
}
}
}
}

View File

@ -36,7 +36,8 @@ struct LocalAccountAvatarView: View {
func loadImage() {
let controller = MastodonController.getForAccount(localAccountInfo)
controller.getOwnAccount { (account) in
controller.getOwnAccount { (result) in
guard case let .success(account) = result else { return }
_ = ImageCache.avatars.get(account.avatar) { (data) in
if let data = data, let image = UIImage(data: data) {
DispatchQueue.main.async {

View File

@ -16,7 +16,9 @@ class MyProfileViewController: ProfileViewController {
title = "My Profile"
tabBarItem.image = UIImage(systemName: "person.fill")
mastodonController.getOwnAccount { (account) in
mastodonController.getOwnAccount { (result) in
guard case let .success(account) = result else { return }
DispatchQueue.main.async {
self.accountID = account.id
}