From caeded9561866446b56f8088368a9caf2448203b Mon Sep 17 00:00:00 2001 From: Nikita Semenov Date: Wed, 11 Jan 2023 13:25:20 +0300 Subject: [PATCH] fix: searching deeplink handler in navigation stack --- .../UIViewController+DeeplinkHandler.swift | 44 ++++++++++++++++++- .../Sources/TIDeeplinkService.swift | 13 ++++-- .../TIDeeplink.podspec | 0 3 files changed, 51 insertions(+), 6 deletions(-) rename TIDeepLink/Sources/TIDeepLinkService.swift => TIDeeplink/Sources/TIDeeplinkService.swift (88%) rename TIDeepLink/TIDeepLink.podspec => TIDeeplink/TIDeeplink.podspec (100%) diff --git a/TIDeepLink/Sources/DeeplinkHandler/Helpers/UIViewController+DeeplinkHandler.swift b/TIDeepLink/Sources/DeeplinkHandler/Helpers/UIViewController+DeeplinkHandler.swift index aba552c3..9c15d0fd 100644 --- a/TIDeepLink/Sources/DeeplinkHandler/Helpers/UIViewController+DeeplinkHandler.swift +++ b/TIDeepLink/Sources/DeeplinkHandler/Helpers/UIViewController+DeeplinkHandler.swift @@ -25,13 +25,53 @@ import UIKit public typealias DeeplinkHandlerViewController = DeeplinkHandler & UIViewController public extension UIViewController { + func findHandler(for deeplink: DeeplinkType) -> DeeplinkHandlerViewController? { if let deeplinksHandler = self as? DeeplinkHandlerViewController, deeplinksHandler.canHandle(deeplink: deeplink) { return deeplinksHandler } - let deeplinksHandler = presentedViewController?.findHandler(for: deeplink) - return deeplinksHandler + if let deeplinksHandler = presentedViewController?.findHandler(for: deeplink) { + return deeplinksHandler + } + + return findHandlerInViewHierarchy(for: deeplink) + } + + private func findHandlerInViewHierarchy(for deeplink: DeeplinkType) -> DeeplinkHandlerViewController? { + switch self { + case let navController as UINavigationController: + return navController.viewControllers.reversed().findHadler(for: deeplink) + + case let tabController as UITabBarController: + if let deeplinksHandler = tabController.selectedViewController?.findHandler(for: deeplink) { + return deeplinksHandler + } else if var tabControllers = tabController.viewControllers { + if tabController.selectedIndex != NSNotFound { + tabControllers.remove(at: tabController.selectedIndex) + } + + if let deeplinksHandler = tabControllers.findHadler(for: deeplink) { + return deeplinksHandler + } + } + + default: + return nil + } + + return nil + } +} + +private extension Sequence where Element: UIViewController { + func findHadler(for deeplink: DeeplinkType) -> DeeplinkHandlerViewController? { + for controller in self { + if let deeplinksHandler = controller.findHandler(for: deeplink) { + return deeplinksHandler + } + } + return nil } } diff --git a/TIDeepLink/Sources/TIDeepLinkService.swift b/TIDeeplink/Sources/TIDeeplinkService.swift similarity index 88% rename from TIDeepLink/Sources/TIDeepLinkService.swift rename to TIDeeplink/Sources/TIDeeplinkService.swift index eaf18322..7aa6503b 100644 --- a/TIDeepLink/Sources/TIDeepLinkService.swift +++ b/TIDeeplink/Sources/TIDeeplinkService.swift @@ -33,7 +33,7 @@ public final class TIDeeplinksService { private var pendingDeeplink: DeeplinkType? - private(set) var isProcessDeeplink = false + private(set) var isProcessingDeeplink = false // MARK: - Public properties @@ -48,6 +48,11 @@ public final class TIDeeplinksService { // MARK: - Public methods + public func configure(mapper: DeeplinkMapper, handler: DeeplinkHandler) { + deeplinkMapper = mapper + deeplinkHandler = handler + } + @discardableResult public func deferredHandle(url: URL) -> Bool { pendingDeeplink = deeplinkMapper?.map(url: url) @@ -57,7 +62,7 @@ public final class TIDeeplinksService { public func reset() { operationQueue.cancelAllOperations() pendingDeeplink = nil - isProcessDeeplink = false + isProcessingDeeplink = false } public func tryHandle() { @@ -76,13 +81,13 @@ public final class TIDeeplinksService { } operationQueue.addOperation { [weak self] in - self?.isProcessDeeplink = true + self?.isProcessingDeeplink = true self?.pendingDeeplink = nil } operationQueue.addOperations(lastOperation.flattenDependencies + [lastOperation], waitUntilFinished: false) operationQueue.addOperation { [weak self] in - self?.isProcessDeeplink = false + self?.isProcessingDeeplink = false } } } diff --git a/TIDeepLink/TIDeepLink.podspec b/TIDeeplink/TIDeeplink.podspec similarity index 100% rename from TIDeepLink/TIDeepLink.podspec rename to TIDeeplink/TIDeeplink.podspec