From 2eead1f9debbba696afb42b000cd9572ab062558 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Thu, 22 Aug 2024 14:17:04 -0400 Subject: [PATCH] Revert "Fix crash when opening push notification while VC modally presented" This reverts commit 0f2a85b1088cd7d8a27924b37715c465c2a52420. This fixes state restoration happening asynchronously and causing the new tab bar animation to run. --- Tusker/AppDelegate.swift | 7 ++-- Tusker/Scenes/MainSceneDelegate.swift | 10 ++---- ...ountSwitchingContainerViewController.swift | 14 ++++---- Tusker/Screens/Main/Duckable+Root.swift | 4 +-- .../Main/MainSplitViewController.swift | 7 ++-- .../Main/MainTabBarViewController.swift | 3 +- .../Main/TuskerRootViewController.swift | 3 +- Tusker/Shortcuts/AppShortcutItems.swift | 4 +-- .../Shortcuts/NSUserActivity+Extensions.swift | 4 +-- .../UserActivityHandlingContext.swift | 25 ++++--------- Tusker/Shortcuts/UserActivityManager.swift | 36 +++++++++---------- Tusker/Shortcuts/UserActivityType.swift | 2 +- 12 files changed, 49 insertions(+), 70 deletions(-) diff --git a/Tusker/AppDelegate.swift b/Tusker/AppDelegate.swift index 8810bf13..aa2826fd 100644 --- a/Tusker/AppDelegate.swift +++ b/Tusker/AppDelegate.swift @@ -295,10 +295,9 @@ extension AppDelegate: UNUserNotificationCenterDelegate { // if the scene is already active, then we animate the account switching if necessary delegate.activateAccount(account, animated: scene.activationState == .foregroundActive) - rootViewController.select(route: .notifications, animated: false) { - let vc = NotificationLoadingViewController(notificationID: notificationID, mastodonController: mastodonController) - rootViewController.getNavigationController().pushViewController(vc, animated: false) - } + rootViewController.select(route: .notifications, animated: false) + let vc = NotificationLoadingViewController(notificationID: notificationID, mastodonController: mastodonController) + rootViewController.getNavigationController().pushViewController(vc, animated: false) } else { let activity = UserActivityManager.showNotificationActivity(id: notificationID, accountID: accountID) if #available(iOS 17.0, *) { diff --git a/Tusker/Scenes/MainSceneDelegate.swift b/Tusker/Scenes/MainSceneDelegate.swift index 73e4c157..31e5b667 100644 --- a/Tusker/Scenes/MainSceneDelegate.swift +++ b/Tusker/Scenes/MainSceneDelegate.swift @@ -83,9 +83,7 @@ class MainSceneDelegate: UIResponder, UIWindowSceneDelegate, TuskerSceneDelegate } else { context = ActiveAccountUserActivityHandlingContext(isHandoff: true, root: rootViewController!) } - Task(priority: .userInitiated) { - _ = await userActivity.handleResume(manager: UserActivityManager(scene: scene as! UIWindowScene, context: context)) - } + _ = userActivity.handleResume(manager: UserActivityManager(scene: scene as! UIWindowScene, context: context)) } func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) { @@ -193,10 +191,8 @@ class MainSceneDelegate: UIResponder, UIWindowSceneDelegate, TuskerSceneDelegate if let activity = launchActivity { func doRestoreActivity(context: UserActivityHandlingContext) { - Task(priority: .userInitiated) { - _ = await activity.handleResume(manager: UserActivityManager(scene: window!.windowScene!, context: context)) - context.finalize(activity: activity) - } + _ = activity.handleResume(manager: UserActivityManager(scene: window!.windowScene!, context: context)) + context.finalize(activity: activity) } if activity.isStateRestorationActivity { doRestoreActivity(context: StateRestorationUserActivityHandlingContext(root: rootViewController!)) diff --git a/Tusker/Screens/Main/AccountSwitchingContainerViewController.swift b/Tusker/Screens/Main/AccountSwitchingContainerViewController.swift index 45a7d263..32d78808 100644 --- a/Tusker/Screens/Main/AccountSwitchingContainerViewController.swift +++ b/Tusker/Screens/Main/AccountSwitchingContainerViewController.swift @@ -79,12 +79,10 @@ class AccountSwitchingContainerViewController: UIViewController { stateRestorationLogger.debug("AccountSwitchingContainer: reusing existing VC for \(account.id, privacy: .public)") } else { newRoot = newRootProvider() - Task(priority: .userInitiated) { - stateRestorationLogger.debug("AccountSwitchingContainer: restoring \(activity.activityType, privacy: .public) for \(account.id, privacy: .public)") - let context = StateRestorationUserActivityHandlingContext(root: newRoot) - _ = await activity.handleResume(manager: UserActivityManager(scene: view.window!.windowScene!, context: context)) - context.finalize(activity: activity) - } + stateRestorationLogger.debug("AccountSwitchingContainer: restoring \(activity.activityType, privacy: .public) for \(account.id, privacy: .public)") + let context = StateRestorationUserActivityHandlingContext(root: newRoot) + _ = activity.handleResume(manager: UserActivityManager(scene: view.window!.windowScene!, context: context)) + context.finalize(activity: activity) } } else { newRoot = newRootProvider() @@ -161,9 +159,9 @@ extension AccountSwitchingContainerViewController: TuskerRootViewController { root.compose(editing: draft, animated: animated, isDucked: isDucked, completion: completion) } - func select(route: TuskerRoute, animated: Bool, completion: (() -> Void)?) { + func select(route: TuskerRoute, animated: Bool) { loadViewIfNeeded() - root.select(route: route, animated: animated, completion: completion) + root.select(route: route, animated: animated) } func getNavigationDelegate() -> TuskerNavigationDelegate? { diff --git a/Tusker/Screens/Main/Duckable+Root.swift b/Tusker/Screens/Main/Duckable+Root.swift index 5ab80ca5..69d36369 100644 --- a/Tusker/Screens/Main/Duckable+Root.swift +++ b/Tusker/Screens/Main/Duckable+Root.swift @@ -35,8 +35,8 @@ extension DuckableContainerViewController: AccountSwitchableViewController { (child as! TuskerRootViewController).getNavigationController() } - func select(route: TuskerRoute, animated: Bool, completion: (() -> Void)?) { - (child as? TuskerRootViewController)?.select(route: route, animated: animated, completion: completion) + func select(route: TuskerRoute, animated: Bool) { + (child as? TuskerRootViewController)?.select(route: route, animated: animated) } func performSearch(query: String) { diff --git a/Tusker/Screens/Main/MainSplitViewController.swift b/Tusker/Screens/Main/MainSplitViewController.swift index 23f62fe9..c78a2c6b 100644 --- a/Tusker/Screens/Main/MainSplitViewController.swift +++ b/Tusker/Screens/Main/MainSplitViewController.swift @@ -546,14 +546,14 @@ extension MainSplitViewController: StateRestorableViewController { } extension MainSplitViewController: TuskerRootViewController { - func select(route: TuskerRoute, animated: Bool, completion: (() -> Void)?) { + func select(route: TuskerRoute, animated: Bool) { guard traitCollection.horizontalSizeClass != .compact else { - tabBarViewController?.select(route: route, animated: animated, completion: completion) + tabBarViewController?.select(route: route, animated: animated) return } guard presentedViewController == nil else { dismiss(animated: animated) { - self.select(route: route, animated: animated, completion: completion) + self.select(route: route, animated: animated) } return } @@ -579,7 +579,6 @@ extension MainSplitViewController: TuskerRootViewController { let oldItem = sidebar.selectedItem sidebar.select(item: item, animated: false) select(newItem: item, oldItem: oldItem) - completion?() } func getNavigationDelegate() -> TuskerNavigationDelegate? { diff --git a/Tusker/Screens/Main/MainTabBarViewController.swift b/Tusker/Screens/Main/MainTabBarViewController.swift index 57808a2b..e3473b28 100644 --- a/Tusker/Screens/Main/MainTabBarViewController.swift +++ b/Tusker/Screens/Main/MainTabBarViewController.swift @@ -148,7 +148,7 @@ extension MainTabBarViewController: UITabBarControllerDelegate { } extension MainTabBarViewController: TuskerRootViewController { - func select(route: TuskerRoute, animated: Bool, completion: (() -> Void)?) { + func select(route: TuskerRoute, animated: Bool) { switch route { case .timelines: select(tab: .timelines, dismissPresented: true) @@ -169,7 +169,6 @@ extension MainTabBarViewController: TuskerRootViewController { nav.pushViewController(ListTimelineViewController(for: list, mastodonController: mastodonController), animated: animated) } } - completion?() } func getNavigationDelegate() -> TuskerNavigationDelegate? { diff --git a/Tusker/Screens/Main/TuskerRootViewController.swift b/Tusker/Screens/Main/TuskerRootViewController.swift index d0435430..aa392d95 100644 --- a/Tusker/Screens/Main/TuskerRootViewController.swift +++ b/Tusker/Screens/Main/TuskerRootViewController.swift @@ -12,7 +12,8 @@ import ComposeUI @MainActor protocol TuskerRootViewController: UIViewController, StateRestorableViewController, StatusBarTappableViewController { func compose(editing draft: Draft?, animated: Bool, isDucked: Bool, completion: (() -> Void)?) - func select(route: TuskerRoute, animated: Bool, completion: (() -> Void)?) + func select(route: TuskerRoute, animated: Bool) + func getTabController(tab: MainTabBarViewController.Tab) -> UIViewController? func getNavigationDelegate() -> TuskerNavigationDelegate? func getNavigationController() -> NavigationControllerProtocol func performSearch(query: String) diff --git a/Tusker/Shortcuts/AppShortcutItems.swift b/Tusker/Shortcuts/AppShortcutItems.swift index af6b6883..baa5905a 100644 --- a/Tusker/Shortcuts/AppShortcutItems.swift +++ b/Tusker/Shortcuts/AppShortcutItems.swift @@ -44,9 +44,9 @@ enum AppShortcutItem: String, CaseIterable { } switch self { case .showHomeTimeline: - root.select(route: .timelines, animated: false, completion: nil) + root.select(route: .timelines, animated: false) case .showNotifications: - root.select(route: .notifications, animated: false, completion: nil) + root.select(route: .notifications, animated: false) case .composePost: root.compose(editing: nil, animated: false, isDucked: false, completion: nil) } diff --git a/Tusker/Shortcuts/NSUserActivity+Extensions.swift b/Tusker/Shortcuts/NSUserActivity+Extensions.swift index 027211f3..7a460a72 100644 --- a/Tusker/Shortcuts/NSUserActivity+Extensions.swift +++ b/Tusker/Shortcuts/NSUserActivity+Extensions.swift @@ -43,9 +43,9 @@ extension NSUserActivity { } @MainActor - func handleResume(manager: UserActivityManager) async -> Bool { + func handleResume(manager: UserActivityManager) -> Bool { guard let type = UserActivityType(rawValue: activityType) else { return false } - await type.handle(manager)(self) + type.handle(manager)(self) return true } diff --git a/Tusker/Shortcuts/UserActivityHandlingContext.swift b/Tusker/Shortcuts/UserActivityHandlingContext.swift index 312223c7..5ee9f185 100644 --- a/Tusker/Shortcuts/UserActivityHandlingContext.swift +++ b/Tusker/Shortcuts/UserActivityHandlingContext.swift @@ -16,8 +16,7 @@ import ComposeUI protocol UserActivityHandlingContext { var isHandoff: Bool { get } - func select(route: TuskerRoute) async - func select(route: TuskerRoute, completion: (() -> Void)?) + func select(route: TuskerRoute) func present(_ vc: UIViewController) var topViewController: UIViewController? { get } @@ -29,16 +28,6 @@ protocol UserActivityHandlingContext { func finalize(activity: NSUserActivity) } -extension UserActivityHandlingContext { - func select(route: TuskerRoute) async { - await withCheckedContinuation { continuation in - select(route: route) { - continuation.resume() - } - } - } -} - struct ActiveAccountUserActivityHandlingContext: UserActivityHandlingContext { let isHandoff: Bool let root: TuskerRootViewController @@ -46,8 +35,8 @@ struct ActiveAccountUserActivityHandlingContext: UserActivityHandlingContext { root.getNavigationDelegate()! } - func select(route: TuskerRoute, completion: (() -> Void)?) { - root.select(route: route, animated: true, completion: completion) + func select(route: TuskerRoute) { + root.select(route: route, animated: true) } func present(_ vc: UIViewController) { @@ -82,11 +71,9 @@ class StateRestorationUserActivityHandlingContext: UserActivityHandlingContext { var isHandoff: Bool { false } - func select(route: TuskerRoute, completion: (() -> Void)?) { - root.select(route: route, animated: false) { - self.state = .selectedRoute - completion?() - } + func select(route: TuskerRoute) { + root.select(route: route, animated: false) + state = .selectedRoute } var topViewController: UIViewController? { root.getNavigationController().topViewController } diff --git a/Tusker/Shortcuts/UserActivityManager.swift b/Tusker/Shortcuts/UserActivityManager.swift index 9a018447..18b7fbd1 100644 --- a/Tusker/Shortcuts/UserActivityManager.swift +++ b/Tusker/Shortcuts/UserActivityManager.swift @@ -133,8 +133,8 @@ class UserActivityManager { return activity } - func handleCheckNotifications(activity: NSUserActivity) async { - await context.select(route: .notifications) + func handleCheckNotifications(activity: NSUserActivity) { + context.select(route: .notifications) context.popToRoot() if let notificationsPageController = context.topViewController as? NotificationsPageViewController { notificationsPageController.loadViewIfNeeded() @@ -204,22 +204,22 @@ class UserActivityManager { return (timeline, positionInfo) } - func handleShowTimeline(activity: NSUserActivity) async { + func handleShowTimeline(activity: NSUserActivity) { guard let (timeline, positionInfo) = Self.getTimeline(from: activity) else { return } var timelineVC: TimelineViewController? if let pinned = PinnedTimeline(timeline: timeline), mastodonController.accountPreferences.pinnedTimelines.contains(pinned) { - await context.select(route: .timelines) + context.select(route: .timelines) context.popToRoot() let pageController = context.topViewController as! TimelinesPageViewController pageController.selectTimeline(pinned, animated: false) timelineVC = pageController.currentViewController as? TimelineViewController } else if case .list(let id) = timeline { - await context.select(route: .list(id: id)) + context.select(route: .list(id: id)) timelineVC = context.topViewController as? TimelineViewController } else { - await context.select(route: .explore) + context.select(route: .explore) context.popToRoot() timelineVC = TimelineViewController(for: timeline, mastodonController: mastodonController) context.push(timelineVC!) @@ -249,11 +249,11 @@ class UserActivityManager { return activity.userInfo?["mainStatusID"] as? String } - func handleShowConversation(activity: NSUserActivity) async { + func handleShowConversation(activity: NSUserActivity) { guard let mainStatusID = Self.getConversationStatus(from: activity) else { return } - await context.select(route: .timelines) + context.select(route: .timelines) context.push(ConversationViewController(for: mainStatusID, state: .unknown, mastodonController: mastodonController)) } @@ -274,8 +274,8 @@ class UserActivityManager { return activity.userInfo?["query"] as? String } - func handleSearch(activity: NSUserActivity) async { - await context.select(route: .explore) + func handleSearch(activity: NSUserActivity) { + context.select(route: .explore) context.popToRoot() let searchController: UISearchController @@ -311,8 +311,8 @@ class UserActivityManager { return activity } - func handleBookmarks(activity: NSUserActivity) async { - await context.select(route: .bookmarks) + func handleBookmarks(activity: NSUserActivity) { + context.select(route: .bookmarks) } // MARK: - My Profile @@ -325,8 +325,8 @@ class UserActivityManager { return activity } - func handleMyProfile(activity: NSUserActivity) async { - await context.select(route: .myProfile) + func handleMyProfile(activity: NSUserActivity) { + context.select(route: .myProfile) } // MARK: - Show Profile @@ -344,11 +344,11 @@ class UserActivityManager { return activity.userInfo?["profileID"] as? String } - func handleShowProfile(activity: NSUserActivity) async { + func handleShowProfile(activity: NSUserActivity) { guard let accountID = Self.getProfile(from: activity) else { return } - await context.select(route: .timelines) + context.select(route: .timelines) context.push(ProfileViewController(accountID: accountID, mastodonController: mastodonController)) } @@ -361,11 +361,11 @@ class UserActivityManager { return activity } - func handleShowNotification(activity: NSUserActivity) async { + func handleShowNotification(activity: NSUserActivity) { guard let notificationID = activity.userInfo?["notificationID"] as? String else { return } - await context.select(route: .notifications) + context.select(route: .notifications) context.push(NotificationLoadingViewController(notificationID: notificationID, mastodonController: mastodonController)) } diff --git a/Tusker/Shortcuts/UserActivityType.swift b/Tusker/Shortcuts/UserActivityType.swift index 090cf8c2..6d7e991f 100644 --- a/Tusker/Shortcuts/UserActivityType.swift +++ b/Tusker/Shortcuts/UserActivityType.swift @@ -23,7 +23,7 @@ enum UserActivityType: String { extension UserActivityType { @MainActor - var handle: (UserActivityManager) -> @MainActor (NSUserActivity) async -> Void { + var handle: (UserActivityManager) -> @MainActor (NSUserActivity) -> Void { switch self { case .mainScene: fatalError("cannot handle main scene activity")