Make FeedlyOAuthAccountAuthorizationOperation not a MainThreadOperation, since we’re moving away from MainThreadOperationQueue.

This commit is contained in:
Brent Simmons 2024-05-15 09:31:16 -07:00
parent ab4d51b462
commit 01f08b9f27
3 changed files with 39 additions and 26 deletions

View File

@ -25,7 +25,7 @@ public enum FeedlyOAuthAccountAuthorizationOperationError: LocalizedError {
return NSLocalizedString("There is already a Feedly account with that username created.", comment: "Duplicate Error") return NSLocalizedString("There is already a Feedly account with that username created.", comment: "Duplicate Error")
} }
} }
@MainActor @objc public final class FeedlyOAuthAccountAuthorizationOperation: NSObject, MainThreadOperation, ASWebAuthenticationPresentationContextProviding { @MainActor @objc public final class FeedlyOAuthAccountAuthorizationOperation: NSObject {
public var isCanceled: Bool = false { public var isCanceled: Bool = false {
didSet { didSet {
@ -34,21 +34,17 @@ public enum FeedlyOAuthAccountAuthorizationOperationError: LocalizedError {
} }
} }
} }
public var id: Int?
public weak var operationDelegate: MainThreadOperationDelegate? public var completionBlock: ((FeedlyOAuthAccountAuthorizationOperation) -> Void)?
public var name: String?
public var completionBlock: MainThreadOperation.MainThreadOperationCompletionBlock?
public weak var presentationAnchor: ASPresentationAnchor? public weak var presentationAnchor: ASPresentationAnchor?
public weak var delegate: FeedlyOAuthAccountAuthorizationOperationDelegate? public weak var delegate: FeedlyOAuthAccountAuthorizationOperationDelegate?
private let accountType: AccountType
private let oauthClient: OAuthAuthorizationClient private let oauthClient: OAuthAuthorizationClient
private var session: ASWebAuthenticationSession? private var session: ASWebAuthenticationSession?
private let secretsProvider: SecretsProvider private let secretsProvider: SecretsProvider
public init(accountType: AccountType, secretsProvider: SecretsProvider) { public init(secretsProvider: SecretsProvider) {
self.accountType = accountType
self.secretsProvider = secretsProvider self.secretsProvider = secretsProvider
self.oauthClient = FeedlyAPICaller.API.cloud.oauthAuthorizationClient(secretsProvider: secretsProvider) self.oauthClient = FeedlyAPICaller.API.cloud.oauthAuthorizationClient(secretsProvider: secretsProvider)
} }
@ -132,17 +128,6 @@ public enum FeedlyOAuthAccountAuthorizationOperationError: LocalizedError {
} }
} }
nonisolated public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
MainActor.assumeIsolated {
guard let anchor = presentationAnchor else {
fatalError("\(self) has outlived presentation anchor.")
}
return anchor
}
}
@MainActor private func saveAccount(for grant: OAuthAuthorizationGrant) { @MainActor private func saveAccount(for grant: OAuthAuthorizationGrant) {
guard !AccountManager.shared.duplicateServiceAccount(type: .feedly, username: grant.accessToken.username) else { guard !AccountManager.shared.duplicateServiceAccount(type: .feedly, username: grant.accessToken.username) else {
didFinish(FeedlyOAuthAccountAuthorizationOperationError.duplicateAccount) didFinish(FeedlyOAuthAccountAuthorizationOperationError.duplicateAccount)
@ -172,7 +157,7 @@ public enum FeedlyOAuthAccountAuthorizationOperationError: LocalizedError {
@MainActor private func didFinish() { @MainActor private func didFinish() {
assert(Thread.isMainThread) assert(Thread.isMainThread)
operationDelegate?.operationDidComplete(self) // operationDelegate?.operationDidComplete(self)
} }
@MainActor private func didFinish(_ error: Error) { @MainActor private func didFinish(_ error: Error) {
@ -181,3 +166,18 @@ public enum FeedlyOAuthAccountAuthorizationOperationError: LocalizedError {
didFinish() didFinish()
} }
} }
// MARK: - ASWebAuthenticationPresentationContextProviding
extension FeedlyOAuthAccountAuthorizationOperation: ASWebAuthenticationPresentationContextProviding {
nonisolated public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
MainActor.assumeIsolated {
guard let anchor = presentationAnchor else {
fatalError("\(self) has outlived presentation anchor.")
}
return anchor
}
}
}

View File

@ -185,11 +185,13 @@ extension AccountsPreferencesViewController: AccountsPreferencesAddAccountDelega
addAccountWindowController = accountsReaderAPIWindowController addAccountWindowController = accountsReaderAPIWindowController
case .feedly: case .feedly:
let addAccount = FeedlyOAuthAccountAuthorizationOperation(accountType: .feedly, secretsProvider: Secrets()) let addAccount = FeedlyOAuthAccountAuthorizationOperation(secretsProvider: Secrets())
addAccount.delegate = self addAccount.delegate = self
addAccount.presentationAnchor = self.view.window! addAccount.presentationAnchor = self.view.window!
runAwaitingFeedlyLoginAlertModal(forLifetimeOf: addAccount) runAwaitingFeedlyLoginAlertModal(forLifetimeOf: addAccount)
MainThreadOperationQueue.shared.add(addAccount) Task { @MainActor in
addAccount.run()
}
case .newsBlur: case .newsBlur:
let accountsNewsBlurWindowController = AccountsNewsBlurWindowController() let accountsNewsBlurWindowController = AccountsNewsBlurWindowController()
@ -273,6 +275,8 @@ private extension AccountsPreferencesViewController {
} }
// MARK: - FeedlyOAuthAccountAuthorizationOperationDelegate
extension AccountsPreferencesViewController: FeedlyOAuthAccountAuthorizationOperationDelegate { extension AccountsPreferencesViewController: FeedlyOAuthAccountAuthorizationOperationDelegate {
func oauthAccountAuthorizationOperation(_ operation: FeedlyOAuthAccountAuthorizationOperation, didCreate account: Account) { func oauthAccountAuthorizationOperation(_ operation: FeedlyOAuthAccountAuthorizationOperation, didCreate account: Account) {

View File

@ -15,7 +15,7 @@ protocol AddAccountDismissDelegate: UIViewController {
@MainActor func dismiss() @MainActor func dismiss()
} }
class AddAccountViewController: UITableViewController, AddAccountDismissDelegate { final class AddAccountViewController: UITableViewController, AddAccountDismissDelegate {
private enum AddAccountSections: Int, CaseIterable { private enum AddAccountSections: Int, CaseIterable {
case local = 0 case local = 0
@ -67,6 +67,8 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
} }
} }
private var feedlyAddAccountOperation: FeedlyOAuthAccountAuthorizationOperation?
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
} }
@ -198,10 +200,15 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
addViewController.delegate = self addViewController.delegate = self
present(navController, animated: true) present(navController, animated: true)
case .feedly: case .feedly:
let addAccount = FeedlyOAuthAccountAuthorizationOperation(accountType: .feedly, secretsProvider: Secrets()) let addAccount = FeedlyOAuthAccountAuthorizationOperation(secretsProvider: Secrets())
addAccount.delegate = self addAccount.delegate = self
addAccount.presentationAnchor = self.view.window! addAccount.presentationAnchor = self.view.window!
MainThreadOperationQueue.shared.add(addAccount) feedlyAddAccountOperation = addAccount
Task { @MainActor in
addAccount.run()
}
case .newsBlur: case .newsBlur:
let navController = UIStoryboard.account.instantiateViewController(withIdentifier: "NewsBlurAccountNavigationViewController") as! UINavigationController let navController = UIStoryboard.account.instantiateViewController(withIdentifier: "NewsBlurAccountNavigationViewController") as! UINavigationController
navController.modalPresentationStyle = .currentContext navController.modalPresentationStyle = .currentContext
@ -224,6 +231,8 @@ class AddAccountViewController: UITableViewController, AddAccountDismissDelegate
} }
// MARK: - FeedlyOAuthAccountAuthorizationOperationDelegate
extension AddAccountViewController: FeedlyOAuthAccountAuthorizationOperationDelegate { extension AddAccountViewController: FeedlyOAuthAccountAuthorizationOperationDelegate {
func oauthAccountAuthorizationOperation(_ operation: FeedlyOAuthAccountAuthorizationOperation, didCreate account: Account) { func oauthAccountAuthorizationOperation(_ operation: FeedlyOAuthAccountAuthorizationOperation, didCreate account: Account) {