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,23 +84,28 @@ 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 {
self.account = account case let .failure(error):
self.persistentContainer.backgroundContext.perform { completion?(.failure(error))
if let accountMO = self.persistentContainer.account(for: account.id, in: self.persistentContainer.backgroundContext) {
accountMO.updateFrom(apiAccount: account, container: self.persistentContainer) case let .success(account, _):
} else { self.account = account
// the first time the user's account is added to the store, self.persistentContainer.backgroundContext.perform {
// increment its reference count so that it's never removed if let accountMO = self.persistentContainer.account(for: account.id, in: self.persistentContainer.backgroundContext) {
self.persistentContainer.addOrUpdate(account: account, incrementReferenceCount: true) 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) 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 {
// this needs to happen on the main thread because it publishes a new value for the ObservableObject switch result {
let accountInfo = LocalData.shared.addAccount(instanceURL: instanceURL, clientID: clientID, clientSecret: clientSecret, username: account.username, accessToken: accessToken) case let .failure(error):
mastodonController.accountInfo = accountInfo 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)
self.onboardingDelegate?.didFinishOnboarding(account: accountInfo) 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() { 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
} }