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 | 55 | ||||
| -rw-r--r-- | ios/Routing/Router/ApplicationRouterDelegate.swift | 8 | ||||
| -rw-r--r-- | ios/Routing/Router/ApplicationRouterTypes.swift | 20 |
4 files changed, 47 insertions, 40 deletions
diff --git a/ios/Routing/Router/AppRouteProtocol.swift b/ios/Routing/Router/AppRouteProtocol.swift index 85fbd53028..b15776ae27 100644 --- a/ios/Routing/Router/AppRouteProtocol.swift +++ b/ios/Routing/Router/AppRouteProtocol.swift @@ -11,7 +11,7 @@ import Foundation /** Formal protocol describing a group of routes. */ -public protocol AppRouteGroupProtocol: Comparable, Equatable, Hashable { +public protocol AppRouteGroupProtocol: Comparable, Equatable, Hashable, Sendable { /** Returns `true` if group is presented modally, otherwise `false` if group is a part of root view controller. @@ -44,7 +44,7 @@ extension AppRouteGroupProtocol { /** Formal protocol describing a single route. */ -public protocol AppRouteProtocol: Equatable, Hashable { +public protocol AppRouteProtocol: Equatable, Hashable, Sendable { associatedtype RouteGroupType: AppRouteGroupProtocol /** diff --git a/ios/Routing/Router/ApplicationRouter.swift b/ios/Routing/Router/ApplicationRouter.swift index d565875143..c55daf2400 100644 --- a/ios/Routing/Router/ApplicationRouter.swift +++ b/ios/Routing/Router/ApplicationRouter.swift @@ -13,8 +13,9 @@ import UIKit /** Main application router. */ -public final class ApplicationRouter<RouteType: AppRouteProtocol> { - private let logger = Logger(label: "ApplicationRouter") +@MainActor +public final class ApplicationRouter<RouteType: AppRouteProtocol>: Sendable { + nonisolated(unsafe) private let logger = Logger(label: "ApplicationRouter") private(set) var modalStack: [RouteType.RouteGroupType] = [] private(set) var presentedRoutes: [RouteType.RouteGroupType: [PresentedRoute<RouteType>]] = [:] @@ -95,7 +96,7 @@ public final class ApplicationRouter<RouteType: AppRouteProtocol> { _ route: RouteType, animated: Bool, metadata: Any?, - completion: @escaping (PendingPresentationResult) -> Void + completion: @escaping @Sendable @MainActor (PendingPresentationResult) -> Void ) { /** Pass sub-route for routes supporting sub-navigation. @@ -160,15 +161,19 @@ public final class ApplicationRouter<RouteType: AppRouteProtocol> { /* Synchronize router when modal controllers are removed by swipe. */ - if let presentable = coordinator as? Presentable { - presentable.onInteractiveDismissal { [weak self] coordinator in - self?.handleInteractiveDismissal(route: route, coordinator: coordinator) + MainActor.assumeIsolated { + if let presentable = coordinator as? Presentable { + presentable.onInteractiveDismissal { [weak self] coordinator in + MainActor.assumeIsolated { + self?.handleInteractiveDismissal(route: route, coordinator: coordinator) + } + } } - } - self.addPresentedRoute(PresentedRoute(route: route, coordinator: coordinator)) + self.addPresentedRoute(PresentedRoute(route: route, coordinator: coordinator)) - completion(.success) + completion(.success) + } } } else { completion(.drop) @@ -178,7 +183,7 @@ public final class ApplicationRouter<RouteType: AppRouteProtocol> { private func dismissGroup( _ dismissGroup: RouteType.RouteGroupType, animated: Bool, - completion: @escaping (PendingDismissalResult) -> Void + completion: @escaping @Sendable (PendingDismissalResult) -> Void ) { /** Check if routes corresponding to the group requested for dismissal are present. @@ -224,7 +229,7 @@ public final class ApplicationRouter<RouteType: AppRouteProtocol> { private func dismissRoute( _ dismissRoute: RouteType, animated: Bool, - completion: @escaping (PendingDismissalResult) -> Void + completion: @escaping @Sendable (PendingDismissalResult) -> Void ) { var routes = presentedRoutes[dismissRoute.routeGroup] ?? [] @@ -304,19 +309,21 @@ public final class ApplicationRouter<RouteType: AppRouteProtocol> { case let .dismiss(dismissMatch): handleDismissal(dismissMatch, animated: pendingRoute.animated) { result in - switch result { - case .success, .drop: - self.finishPendingRoute(pendingRoute) + MainActor.assumeIsolated { + switch result { + case .success, .drop: + self.finishPendingRoute(pendingRoute) - case .blockedByModalAbove: - /** - If router cannot dismiss modal because there is one above, - try walking down the queue and see if there is a dismissal request that could - resolve that. - */ - self.processPendingRoutes( - skipRouteGroups: skipRouteGroups.union([dismissMatch.routeGroup]) - ) + case .blockedByModalAbove: + /** + If router cannot dismiss modal because there is one above, + try walking down the queue and see if there is a dismissal request that could + resolve that. + */ + self.processPendingRoutes( + skipRouteGroups: skipRouteGroups.union([dismissMatch.routeGroup]) + ) + } } } } @@ -325,7 +332,7 @@ public final class ApplicationRouter<RouteType: AppRouteProtocol> { private func handleDismissal( _ dismissMatch: DismissMatch<RouteType>, animated: Bool, - completion: @escaping (PendingDismissalResult) -> Void + completion: @escaping @Sendable (PendingDismissalResult) -> Void ) { switch dismissMatch { case let .singleRoute(route): diff --git a/ios/Routing/Router/ApplicationRouterDelegate.swift b/ios/Routing/Router/ApplicationRouterDelegate.swift index a98870d303..2200066a1f 100644 --- a/ios/Routing/Router/ApplicationRouterDelegate.swift +++ b/ios/Routing/Router/ApplicationRouterDelegate.swift @@ -11,7 +11,7 @@ import Foundation /** Application router delegate */ -public protocol ApplicationRouterDelegate<RouteType>: AnyObject { +public protocol ApplicationRouterDelegate<RouteType>: AnyObject, Sendable { associatedtype RouteType: AppRouteProtocol /** @@ -21,7 +21,7 @@ public protocol ApplicationRouterDelegate<RouteType>: AnyObject { _ router: ApplicationRouter<RouteType>, presentWithContext context: RoutePresentationContext<RouteType>, animated: Bool, - completion: @escaping (Coordinator) -> Void + completion: @escaping @Sendable (Coordinator) -> Void ) /** @@ -30,7 +30,7 @@ public protocol ApplicationRouterDelegate<RouteType>: AnyObject { func applicationRouter( _ router: ApplicationRouter<RouteType>, dismissWithContext context: RouteDismissalContext<RouteType>, - completion: @escaping () -> Void + completion: @escaping @Sendable () -> Void ) /** @@ -57,6 +57,6 @@ public protocol ApplicationRouterDelegate<RouteType>: AnyObject { func applicationRouter( _ router: ApplicationRouter<RouteType>, handleSubNavigationWithContext context: RouteSubnavigationContext<RouteType>, - completion: @escaping () -> Void + completion: @escaping @Sendable @MainActor () -> Void ) } diff --git a/ios/Routing/Router/ApplicationRouterTypes.swift b/ios/Routing/Router/ApplicationRouterTypes.swift index 7be142adaf..1a661dfd2a 100644 --- a/ios/Routing/Router/ApplicationRouterTypes.swift +++ b/ios/Routing/Router/ApplicationRouterTypes.swift @@ -11,10 +11,10 @@ import Foundation /** Struct describing a routing request for presentation or dismissal. */ -struct PendingRoute<RouteType: AppRouteProtocol> { +struct PendingRoute<RouteType: AppRouteProtocol>: Sendable { var operation: RouteOperation<RouteType> var animated: Bool - var metadata: Any? + nonisolated(unsafe) var metadata: Any? } extension PendingRoute: Equatable { @@ -26,7 +26,7 @@ extension PendingRoute: Equatable { /** Enum type describing an attempt to fulfill the route presentation request. **/ -enum PendingPresentationResult { +enum PendingPresentationResult: Sendable { /** Successfully presented the route. */ @@ -52,7 +52,7 @@ enum PendingPresentationResult { /** Enum type describing an attempt to fulfill the route dismissal request. */ -enum PendingDismissalResult { +enum PendingDismissalResult: Sendable { /** Successfully dismissed the route. */ @@ -76,7 +76,7 @@ enum PendingDismissalResult { /** Enum describing operation over the route. */ -enum RouteOperation<RouteType: AppRouteProtocol>: Equatable, CustomDebugStringConvertible { +enum RouteOperation<RouteType: AppRouteProtocol>: Equatable, CustomDebugStringConvertible, Sendable { /** Present route. */ @@ -114,7 +114,7 @@ enum RouteOperation<RouteType: AppRouteProtocol>: Equatable, CustomDebugStringCo /** Enum type describing a single route or a group of routes requested to be dismissed. */ -enum DismissMatch<RouteType: AppRouteProtocol>: Equatable, CustomDebugStringConvertible { +enum DismissMatch<RouteType: AppRouteProtocol>: Equatable, CustomDebugStringConvertible, Sendable { case group(RouteType.RouteGroupType) case singleRoute(RouteType) @@ -143,7 +143,7 @@ enum DismissMatch<RouteType: AppRouteProtocol>: Equatable, CustomDebugStringConv /** Struct describing presented route. */ -public struct PresentedRoute<RouteType: AppRouteProtocol>: Equatable { +public struct PresentedRoute<RouteType: AppRouteProtocol>: Equatable, Sendable { public var route: RouteType public var coordinator: Coordinator } @@ -171,7 +171,7 @@ public struct RouteDismissalContext<RouteType: AppRouteProtocol> { /** Struct holding information used by delegate to perform presentation of a specific route. */ -public struct RoutePresentationContext<RouteType: AppRouteProtocol> { +public struct RoutePresentationContext<RouteType: AppRouteProtocol>: Sendable { /** Route that's being presented. */ @@ -185,13 +185,13 @@ public struct RoutePresentationContext<RouteType: AppRouteProtocol> { /** Metadata associated with the route. */ - public var metadata: Any? + nonisolated(unsafe) public var metadata: Any? } /** Struct holding information used by delegate to perform sub-navigation of the route in subject. */ -public struct RouteSubnavigationContext<RouteType: AppRouteProtocol> { +public struct RouteSubnavigationContext<RouteType: AppRouteProtocol>: Sendable { public var presentedRoute: PresentedRoute<RouteType> public var route: RouteType public var isAnimated: Bool |
