diff options
Diffstat (limited to 'ios/Routing/Router')
| -rw-r--r-- | ios/Routing/Router/AppRouteProtocol.swift | 4 | ||||
| -rw-r--r-- | ios/Routing/Router/ApplicationRouter.swift | 27 | ||||
| -rw-r--r-- | ios/Routing/Router/ApplicationRouterDelegate.swift | 2 | ||||
| -rw-r--r-- | ios/Routing/Router/ApplicationRouterTypes.swift | 53 |
4 files changed, 74 insertions, 12 deletions
diff --git a/ios/Routing/Router/AppRouteProtocol.swift b/ios/Routing/Router/AppRouteProtocol.swift index 1843183958..85fbd53028 100644 --- a/ios/Routing/Router/AppRouteProtocol.swift +++ b/ios/Routing/Router/AppRouteProtocol.swift @@ -35,6 +35,10 @@ extension AppRouteGroupProtocol { public static func < (lhs: Self, rhs: Self) -> Bool { lhs.modalLevel < rhs.modalLevel } + + public static func <= (lhs: Self, rhs: Self) -> Bool { + lhs.modalLevel <= rhs.modalLevel + } } /** diff --git a/ios/Routing/Router/ApplicationRouter.swift b/ios/Routing/Router/ApplicationRouter.swift index 2de0cbc3ff..d565875143 100644 --- a/ios/Routing/Router/ApplicationRouter.swift +++ b/ios/Routing/Router/ApplicationRouter.swift @@ -53,10 +53,11 @@ public final class ApplicationRouter<RouteType: AppRouteProtocol> { /** Enqueue route for presetnation. */ - public func present(_ route: RouteType, animated: Bool = true) { + public func present(_ route: RouteType, animated: Bool = true, metadata: Any? = nil) { enqueue(PendingRoute( operation: .present(route), - animated: animated + animated: animated, + metadata: metadata )) } @@ -81,7 +82,7 @@ public final class ApplicationRouter<RouteType: AppRouteProtocol> { } private func enqueue(_ pendingRoute: PendingRoute<RouteType>) { - logger.debug("Enqueue \(pendingRoute.operation).") + logger.debug("\(pendingRoute.operation).") pendingRoutes.append(pendingRoute) @@ -93,6 +94,7 @@ public final class ApplicationRouter<RouteType: AppRouteProtocol> { private func presentRoute( _ route: RouteType, animated: Bool, + metadata: Any?, completion: @escaping (PendingPresentationResult) -> Void ) { /** @@ -117,7 +119,7 @@ public final class ApplicationRouter<RouteType: AppRouteProtocol> { } /** - Drop duplicate routes. + Drop duplicate exclusive routes. */ if route.isExclusive, modalStack.contains(route.routeGroup) { completion(.drop) @@ -135,8 +137,15 @@ public final class ApplicationRouter<RouteType: AppRouteProtocol> { /** Check if route can be presented above the last route in the modal stack. */ - if let lastRouteGroup = modalStack.last, route.routeGroup.isModal, - (lastRouteGroup > route.routeGroup) || (route.isExclusive && lastRouteGroup == route.routeGroup) { + if let + // Get current modal route. + lastRouteGroup = modalStack.last, + // Check if incoming route is modal. + route.routeGroup.isModal, + // Check whether incoming route can be presented on top of current. + (lastRouteGroup > route.routeGroup) || + // OR, check whether incoming exclusive route can be presented on top of current. + (lastRouteGroup >= route.routeGroup && route.isExclusive) { completion(.blockedByModalContext) return } @@ -145,7 +154,9 @@ public final class ApplicationRouter<RouteType: AppRouteProtocol> { Consult with delegate whether the route should still be presented. */ if delegate.applicationRouter(self, shouldPresent: route) { - delegate.applicationRouter(self, route: route, animated: animated) { coordinator in + let context = RoutePresentationContext(route: route, isAnimated: animated, metadata: metadata) + + delegate.applicationRouter(self, presentWithContext: context, animated: animated) { coordinator in /* Synchronize router when modal controllers are removed by swipe. */ @@ -276,7 +287,7 @@ public final class ApplicationRouter<RouteType: AppRouteProtocol> { switch pendingRoute.operation { case let .present(route): - presentRoute(route, animated: pendingRoute.animated) { result in + presentRoute(route, animated: pendingRoute.animated, metadata: pendingRoute.metadata) { result in switch result { case .success, .drop: self.finishPendingRoute(pendingRoute) diff --git a/ios/Routing/Router/ApplicationRouterDelegate.swift b/ios/Routing/Router/ApplicationRouterDelegate.swift index ecccb15415..a98870d303 100644 --- a/ios/Routing/Router/ApplicationRouterDelegate.swift +++ b/ios/Routing/Router/ApplicationRouterDelegate.swift @@ -19,7 +19,7 @@ public protocol ApplicationRouterDelegate<RouteType>: AnyObject { */ func applicationRouter( _ router: ApplicationRouter<RouteType>, - route: RouteType, + presentWithContext context: RoutePresentationContext<RouteType>, animated: Bool, completion: @escaping (Coordinator) -> Void ) diff --git a/ios/Routing/Router/ApplicationRouterTypes.swift b/ios/Routing/Router/ApplicationRouterTypes.swift index 1dfd128c0a..7be142adaf 100644 --- a/ios/Routing/Router/ApplicationRouterTypes.swift +++ b/ios/Routing/Router/ApplicationRouterTypes.swift @@ -11,9 +11,16 @@ import Foundation /** Struct describing a routing request for presentation or dismissal. */ -struct PendingRoute<RouteType: AppRouteProtocol>: Equatable { +struct PendingRoute<RouteType: AppRouteProtocol> { var operation: RouteOperation<RouteType> var animated: Bool + var metadata: Any? +} + +extension PendingRoute: Equatable { + static func == (lhs: PendingRoute<RouteType>, rhs: PendingRoute<RouteType>) -> Bool { + lhs.operation == rhs.operation + } } /** @@ -69,7 +76,7 @@ enum PendingDismissalResult { /** Enum describing operation over the route. */ -enum RouteOperation<RouteType: AppRouteProtocol>: Equatable { +enum RouteOperation<RouteType: AppRouteProtocol>: Equatable, CustomDebugStringConvertible { /** Present route. */ @@ -91,12 +98,23 @@ enum RouteOperation<RouteType: AppRouteProtocol>: Equatable { return dismissMatch.routeGroup } } + + var debugDescription: String { + let action: String + switch self { + case let .present(routeType): + action = "Presenting .\(routeType)" + case let .dismiss(match): + action = "Dismissing .\(match)" + } + return "\(action)" + } } /** Enum type describing a single route or a group of routes requested to be dismissed. */ -enum DismissMatch<RouteType: AppRouteProtocol>: Equatable { +enum DismissMatch<RouteType: AppRouteProtocol>: Equatable, CustomDebugStringConvertible { case group(RouteType.RouteGroupType) case singleRoute(RouteType) @@ -111,6 +129,15 @@ enum DismissMatch<RouteType: AppRouteProtocol>: Equatable { return route.routeGroup } } + + var debugDescription: String { + switch self { + case let .group(group): + return "\(group)" + case let .singleRoute(route): + return "\(route)" + } + } } /** @@ -142,6 +169,26 @@ public struct RouteDismissalContext<RouteType: AppRouteProtocol> { } /** + Struct holding information used by delegate to perform presentation of a specific route. + */ +public struct RoutePresentationContext<RouteType: AppRouteProtocol> { + /** + Route that's being presented. + */ + public var route: RouteType + + /** + Whether transition is animated. + */ + public var isAnimated: Bool + + /** + Metadata associated with the route. + */ + public var metadata: Any? +} + +/** Struct holding information used by delegate to perform sub-navigation of the route in subject. */ public struct RouteSubnavigationContext<RouteType: AppRouteProtocol> { |
