From 54e2ecb3134b08ea9d1c002cea2bef95e7033dee Mon Sep 17 00:00:00 2001 From: Scott Pfeil Date: Mon, 25 Mar 2024 13:29:29 -0400 Subject: [PATCH] Manager updates for navigating to controller. --- ...VMCoreLoadRequestOperation+Extension.swift | 56 +++++++++++-------- .../MVMCoreLoadRequestOperation.m | 10 +++- .../MVMCoreViewManagerProtocol.h | 3 + .../NavigationHandler.swift | 7 +++ .../MVMCore/Singletons/MVMCoreObject.swift | 3 + 5 files changed, 53 insertions(+), 26 deletions(-) diff --git a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation+Extension.swift b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation+Extension.swift index 07bb9a5..a663b94 100644 --- a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation+Extension.swift +++ b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation+Extension.swift @@ -41,37 +41,47 @@ public extension MVMCoreLoadRequestOperation { @objc @MainActor - func checkIfNewControllerIsNeeded(loadObject: MVMCoreLoadObject) -> Bool { + func goToViewController(loadObject: MVMCoreLoadObject) async -> UIViewController? { guard loadObject.requestParameters?.replaceViewIfOnStackElseLoadWithStyle == true, let pageType = loadObject.pageType else { MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: Controller shouldn't be replaced.") - return true + return nil } guard let newVC = MVMCoreViewControllerMappingObject.shared()?.createMFViewController(ofTemplate: loadObject.pageJSON?.optionalStringForKey("template"), pageType: pageType) else { MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: Failed to create a new controller") - return true + return nil } - guard let index = NavigationHandler.shared().navigationController?.viewControllers.firstIndex(where: { controller in - MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: Compare controller pageType:\(pageType) controllerPageType:\((controller as? MVMCoreViewControllerProtocol)?.pageType) type:\(type(of: controller)) newType:\(type(of: newVC))") - return (controller as? MVMCoreViewControllerProtocol)?.pageType == pageType && type(of: controller) == type(of: newVC) - }) else { - MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: No matching controller found.") - return true + let type = type(of: newVC) + guard let viewController = await NavigationHandler.shared().navigateToViewController(of: pageType, controllerType: type) else { + MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: No matching controller found for \(pageType) \(type).") + return nil } - if index == NavigationHandler.shared().navigationController!.viewControllers.count - 1 { - MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: Controller is already showing.") - Task { - MVMCoreLoadRequestOperation.loadFinished(loadObject, loadedViewController: nil, errorObject: nil) - } - } else { - MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: Pop back to controller.") - guard let operation = try? NavigationHandler.shared().getOperationPopToViewController(with: pageType, navigationController: loadObject.requestParameters?.navigationController, delegateObject: loadObject.delegateObject, animated: !(loadObject.requestParameters?.shouldNotAnimatePush ?? false)) else { return true } - Task { - await navigate(with: operation, loadObject: loadObject) - MVMCoreLoadRequestOperation.loadFinished(loadObject, loadedViewController: nil, errorObject: nil) - } - } - return false + MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: Navigated to controller of \(pageType) \(type).") + return viewController +// MVMCoreLoadRequestOperation.loadFinished(loadObject, loadedViewController: nil, errorObject: nil) +// +// +// guard let index = NavigationHandler.shared().navigationController?.viewControllers.firstIndex(where: { controller in +// MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: Compare controller pageType:\(pageType) controllerPageType:\((controller as? MVMCoreViewControllerProtocol)?.pageType) type:\(type(of: controller)) newType:\(type(of: newVC))") +// return (controller as? MVMCoreViewControllerProtocol)?.pageType == pageType && type(of: controller) == type(of: newVC) +// }) else { +// MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: No matching controller found.") +// return true +// } +// if index == NavigationHandler.shared().navigationController!.viewControllers.count - 1 { +// MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: Controller is already showing.") +// Task { +// MVMCoreLoadRequestOperation.loadFinished(loadObject, loadedViewController: nil, errorObject: nil) +// } +// } else { +// MVMCoreLoggingHandler.logDebugMessage(withDelegate: "CACHEDFEED: Pop back to controller.") +// guard let operation = try? NavigationHandler.shared().getOperationPopToViewController(with: pageType, navigationController: loadObject.requestParameters?.navigationController, delegateObject: loadObject.delegateObject, animated: !(loadObject.requestParameters?.shouldNotAnimatePush ?? false)) else { return true } +// Task { +// await navigate(with: operation, loadObject: loadObject) +// MVMCoreLoadRequestOperation.loadFinished(loadObject, loadedViewController: nil, errorObject: nil) +// } +// } +// return false } @objc diff --git a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m index 79ee8b2..7a7d0a9 100644 --- a/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m +++ b/MVMCore/MVMCore/LoadHandling/MVMCoreLoadRequestOperation.m @@ -586,11 +586,15 @@ if (!error.nativeDrivenErrorScreen) { // Server driven screen, create normally [MVMCoreDispatchUtility performBlockOnMainThread:^{ - if ([loadObject.operation checkIfNewControllerIsNeededWithLoadObject:loadObject]) { + [loadObject.operation goToViewControllerWithLoadObject:loadObject completionHandler:^(UIViewController * _Nullable viewController) { [MVMCoreDispatchUtility performBlockInBackground:^{ - [MVMCoreLoadRequestOperation createViewControllerWithLoadObject:loadObject completionHandler:completionHandler]; + if (viewController) { + [MVMCoreLoadRequestOperation loadFinished:loadObject loadedViewController:viewController errorObject:nil]; + } else { + [MVMCoreLoadRequestOperation createViewControllerWithLoadObject:loadObject completionHandler:completionHandler]; + } }]; - } + }]; }]; } else { // Get the proper native error screen from the delegate diff --git a/MVMCore/MVMCore/MainProtocols/MVMCoreViewManagerProtocol.h b/MVMCore/MVMCore/MainProtocols/MVMCoreViewManagerProtocol.h index fda6bee..41438be 100644 --- a/MVMCore/MVMCore/MainProtocols/MVMCoreViewManagerProtocol.h +++ b/MVMCore/MVMCore/MainProtocols/MVMCoreViewManagerProtocol.h @@ -19,6 +19,9 @@ - (nullable NSArray*)getAccessibilityElements; //AccessibilityElements that are owned by Manager. +/// Attempt to navigate to the controller. Return true if navigation occured. +- (void)navigateToViewControllerOfPageType:(nonnull NSString *)pageType controllerType:(_Nullable Class)controllerType completionHandler:(void (^ __nullable)(UIViewController * _Nullable viewController))completionHandler; + @optional /// Notifies the manager that the controller received new data. diff --git a/MVMCore/MVMCore/PresentationHandling/NavigationHandler.swift b/MVMCore/MVMCore/PresentationHandling/NavigationHandler.swift index 2dfde17..ec27379 100644 --- a/MVMCore/MVMCore/PresentationHandling/NavigationHandler.swift +++ b/MVMCore/MVMCore/PresentationHandling/NavigationHandler.swift @@ -189,6 +189,13 @@ public class NavigationHandler { await navigate(with: .pop(navigationController: navigationController, animated: animated), delegateObject: delegateObject) } } + + /// Attempts to go to navigate to a viewcontroller of pageType and controllerType. Returns the view controller if successful + @MainActor + func navigateToViewController(of pageType: String, controllerType: AnyClass?) async -> UIViewController? { + // TODO: Need to manage for present view controllers. + return await MVMCoreObject.sharedInstance()?.viewControllerManager?.navigate(toViewControllerOfPageType: pageType, controllerType: controllerType) + } } extension UINavigationController { diff --git a/MVMCore/MVMCore/Singletons/MVMCoreObject.swift b/MVMCore/MVMCore/Singletons/MVMCoreObject.swift index 2f3fe67..27a14b6 100644 --- a/MVMCore/MVMCore/Singletons/MVMCoreObject.swift +++ b/MVMCore/MVMCore/Singletons/MVMCoreObject.swift @@ -23,6 +23,9 @@ public class MVMCoreObject: NSObject { public var globalLoadDelegate: MVMCoreGlobalLoadProtocol? public var loadingProtocol: MVMCoreLoadingOverlayDelegateProtocol? public var loggingDelegate: MVMCoreLoggingDelegateProtocol? + + /// The main manager of the view controllers in the application. + public weak var viewControllerManager: MVMCoreViewManagerProtocol? /// A reference to the calling application delegate that should be set. For a normal app, could be the UIApplicationDelegate. For watch, could be WKExtensionDelegate. For iMessage, could be MSMessagesAppViewController. etc, etc. Useful for the framework to call delegate specific functions. public weak var applicationDelegate: AnyObject?