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: shadowfacts
GPG Key ID: 94A5AB95422746E5
4 changed files with 36 additions and 20 deletions

View File

@ -84,13 +84,17 @@ class MastodonController {
} }
} }
func getOwnAccount(completion: ((Account) -> Void)? = nil) { func getOwnAccount(completion: ((Result<Account, Client.Error>) -> Void)? = nil) {
if account != nil { if account != nil {
completion?(account) completion?(.success(account))
} else { } else {
let request = Client.getSelfAccount() let request = Client.getSelfAccount()
run(request) { response in run(request) { response in
guard case let .success(account, _) = response else { fatalError() } switch response {
case let .failure(error):
completion?(.failure(error))
case let .success(account, _):
self.account = account self.account = account
self.persistentContainer.backgroundContext.perform { self.persistentContainer.backgroundContext.perform {
if let accountMO = self.persistentContainer.account(for: account.id, in: self.persistentContainer.backgroundContext) { if let accountMO = self.persistentContainer.account(for: account.id, in: self.persistentContainer.backgroundContext) {
@ -100,7 +104,8 @@ class MastodonController {
// increment its reference count so that it's never removed // increment its reference count so that it's never removed
self.persistentContainer.addOrUpdate(account: account, incrementReferenceCount: true) self.persistentContainer.addOrUpdate(account: account, incrementReferenceCount: true)
} }
completion?(account) completion?(.success(account))
}
} }
} }
} }

View File

@ -70,8 +70,15 @@ extension OnboardingViewController: InstanceSelectorTableViewControllerDelegate
let tempAccountInfo = LocalData.UserAccountInfo(id: "temp", instanceURL: instanceURL, clientID: clientID, clientSecret: clientSecret, username: nil, accessToken: accessToken) let tempAccountInfo = LocalData.UserAccountInfo(id: "temp", instanceURL: instanceURL, clientID: clientID, clientSecret: clientSecret, username: nil, accessToken: accessToken)
mastodonController.accountInfo = tempAccountInfo mastodonController.accountInfo = tempAccountInfo
mastodonController.getOwnAccount { (account) in mastodonController.getOwnAccount { (result) in
DispatchQueue.main.async { DispatchQueue.main.async {
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 // 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) let accountInfo = LocalData.shared.addAccount(instanceURL: instanceURL, clientID: clientID, clientSecret: clientSecret, username: account.username, accessToken: accessToken)
mastodonController.accountInfo = accountInfo mastodonController.accountInfo = accountInfo
@ -81,6 +88,7 @@ extension OnboardingViewController: InstanceSelectorTableViewControllerDelegate
} }
} }
} }
}
DispatchQueue.main.async { DispatchQueue.main.async {
// Prefer ephemeral sessions to make it easier to sign into multiple accounts on the same instance. // Prefer ephemeral sessions to make it easier to sign into multiple accounts on the same instance.
self.authenticationSession!.prefersEphemeralWebBrowserSession = true self.authenticationSession!.prefersEphemeralWebBrowserSession = true

View File

@ -36,7 +36,8 @@ struct LocalAccountAvatarView: View {
func loadImage() { func loadImage() {
let controller = MastodonController.getForAccount(localAccountInfo) 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 _ = ImageCache.avatars.get(account.avatar) { (data) in
if let data = data, let image = UIImage(data: data) { if let data = data, let image = UIImage(data: data) {
DispatchQueue.main.async { DispatchQueue.main.async {

View File

@ -16,7 +16,9 @@ class MyProfileViewController: ProfileViewController {
title = "My Profile" title = "My Profile"
tabBarItem.image = UIImage(systemName: "person.fill") 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 { DispatchQueue.main.async {
self.accountID = account.id self.accountID = account.id
} }