Skip to content

Commit

Permalink
0.9.3 release: added ability to keep presented VCs when dispatching r…
Browse files Browse the repository at this point in the history
…outes on Fork RoutingUnit type Presenters (i.e. UITabBarController). Additional actions required when opting-in this feature, see methods' documentation.
  • Loading branch information
nikans committed Feb 1, 2019
1 parent d1e5491 commit 49beaee
Show file tree
Hide file tree
Showing 13 changed files with 226 additions and 59 deletions.
2 changes: 1 addition & 1 deletion Example/MonarchRouter/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>0.9.3</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
</dict>
Expand Down
16 changes: 10 additions & 6 deletions Example/MonarchRouterExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
D0A7B9F1219F324200B44C3D /* MonarchRouter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0A7B9EA219F324200B44C3D /* MonarchRouter.framework */; };
D0A7B9F2219F324200B44C3D /* MonarchRouter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D0A7B9EA219F324200B44C3D /* MonarchRouter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
D0A7BA04219F332900B44C3D /* AppRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A7BA03219F332900B44C3D /* AppRouter.swift */; };
D0A7BA0E219F363900B44C3D /* Array+extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A7BA0B219F363900B44C3D /* Array+extension.swift */; };
D0A7BA0E219F363900B44C3D /* Collection+extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A7BA0B219F363900B44C3D /* Collection+extension.swift */; };
D0A7BA0F219F363900B44C3D /* Presenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A7BA0C219F363900B44C3D /* Presenter.swift */; };
D0A7BA10219F363900B44C3D /* RoutingUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A7BA0D219F363900B44C3D /* RoutingUnit.swift */; };
D0A7BA12219F378B00B44C3D /* Presenters.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A7BA11219F378B00B44C3D /* Presenters.swift */; };
Expand Down Expand Up @@ -77,7 +77,7 @@
D0A7B9EC219F324200B44C3D /* MonarchRouter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MonarchRouter.h; sourceTree = "<group>"; };
D0A7B9ED219F324200B44C3D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D0A7BA03219F332900B44C3D /* AppRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppRouter.swift; sourceTree = "<group>"; };
D0A7BA0B219F363900B44C3D /* Array+extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Array+extension.swift"; path = "../../Source/Array+extension.swift"; sourceTree = "<group>"; };
D0A7BA0B219F363900B44C3D /* Collection+extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "Collection+extension.swift"; path = "../../Source/Collection+extension.swift"; sourceTree = "<group>"; };
D0A7BA0C219F363900B44C3D /* Presenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Presenter.swift; path = ../../Source/Presenter.swift; sourceTree = "<group>"; };
D0A7BA0D219F363900B44C3D /* RoutingUnit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RoutingUnit.swift; path = ../../Source/RoutingUnit.swift; sourceTree = "<group>"; };
D0A7BA11219F378B00B44C3D /* Presenters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Presenters.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -174,7 +174,7 @@
D09D0DEE21A46FE300601258 /* PresenterStack.swift */,
D09D0DF021A4703100601258 /* PresenterFork.swift */,
D09D0DF221A470C300601258 /* PresenterSwitcher.swift */,
D0A7BA0B219F363900B44C3D /* Array+extension.swift */,
D0A7BA0B219F363900B44C3D /* Collection+extension.swift */,
D0A7B9EC219F324200B44C3D /* MonarchRouter.h */,
D0A7B9ED219F324200B44C3D /* Info.plist */,
);
Expand Down Expand Up @@ -375,7 +375,7 @@
D09D0DEF21A46FE300601258 /* PresenterStack.swift in Sources */,
D09D0DF121A4703100601258 /* PresenterFork.swift in Sources */,
D0A7BA10219F363900B44C3D /* RoutingUnit.swift in Sources */,
D0A7BA0E219F363900B44C3D /* Array+extension.swift in Sources */,
D0A7BA0E219F363900B44C3D /* Collection+extension.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -460,7 +460,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
Expand Down Expand Up @@ -515,7 +515,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
Expand All @@ -534,6 +534,7 @@
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 892UN3K9E3;
INFOPLIST_FILE = MonarchRouterExample/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -554,6 +555,7 @@
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 892UN3K9E3;
INFOPLIST_FILE = MonarchRouterExample/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand All @@ -580,6 +582,7 @@
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = MonarchRouter/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -611,6 +614,7 @@
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = MonarchRouter/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
20 changes: 16 additions & 4 deletions Example/MonarchRouterExample/AppCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,10 @@ func createCoordinator(dispatcher: ProvidesRouteDispatch, setRootView: @escaping
},
parameters: { (path) -> RouteParameters in
var arguments = RouteParameters()
if let id = path.capturedGroups(withRegex: "firstDetailParametrized/(?<id>[\\w\\-\\.]+)").first { arguments["id"] = id }
if let id = path.capturedGroups(withRegex: "firstDetailParametrized/(?<id>[\\w\\-\\.]+)").first {
arguments["id"] = id
arguments["route"] = AppRoute.firstDetailParametrized(id: id)
}
return arguments
}
)
Expand Down Expand Up @@ -100,7 +103,10 @@ func createCoordinator(dispatcher: ProvidesRouteDispatch, setRootView: @escaping
},
parameters: { (path) -> RouteParameters in
var arguments = RouteParameters()
if let id = path.capturedGroups(withRegex: "third/(?<id>[\\w\\-\\.]+)").first { arguments["id"] = id }
if let id = path.capturedGroups(withRegex: "third/(?<id>[\\w\\-\\.]+)").first {
arguments["id"] = id
arguments["route"] = AppRoute.third(id: id)
}
return arguments
}
)
Expand All @@ -112,7 +118,10 @@ func createCoordinator(dispatcher: ProvidesRouteDispatch, setRootView: @escaping
path.matches("fourth/(?<id>[\\w\\-\\.]+)")
}, parameters: { (path) -> RouteParameters in
var arguments = RouteParameters()
if let id = path.capturedGroups(withRegex: "fourth/(?<id>[\\w\\-\\.]+)").first { arguments["id"] = id }
if let id = path.capturedGroups(withRegex: "fourth/(?<id>[\\w\\-\\.]+)").first {
arguments["id"] = id
arguments["route"] = AppRoute.fourth(id: id)
}
return arguments
}
),
Expand All @@ -130,7 +139,10 @@ func createCoordinator(dispatcher: ProvidesRouteDispatch, setRootView: @escaping
path.matches("modalParametrized/(?<id>[\\w\\-\\.]+)")
}, parameters: { (path) -> RouteParameters in
var arguments = RouteParameters()
if let id = path.capturedGroups(withRegex: "modalParametrized/(?<id>[\\w\\-\\.]+)").first { arguments["id"] = id }
if let id = path.capturedGroups(withRegex: "modalParametrized/(?<id>[\\w\\-\\.]+)").first {
arguments["id"] = id
arguments["route"] = AppRoute.modalParametrized(id: id)
}
return arguments
}
),
Expand Down
10 changes: 10 additions & 0 deletions Example/MonarchRouterExample/AppRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ protocol ProvidesRouteDispatch
/// Extension method to change the route.
/// - parameter route: `AppRoute` to navigate to.
func dispatchRoute(_ route: AppRoute)

/// Extension method to change the route.
/// - parameter route: `AppRoute` to navigate to.
/// - parameter keepSubroutes: Defines should a more long Path should remain, if presented.
/// - warning: If you opt in using `keepSubroutes: false` i.e. for Fork Routers (TabBarController), you have to make sure, that your endpoint VCs call `dispatchRoute(:)` with their respective Path on `viewDidAppear(:)` for navigation controller consistency. See Example implementation for details.
func dispatchRoute(_ route: AppRoute, keepSubroutes: Bool)
}

// Extending `RouterStore` to accept `AppRoute` instead of string Path.
Expand All @@ -75,4 +81,8 @@ extension RouterStore: ProvidesRouteDispatch
func dispatchRoute(_ route: AppRoute) {
dispatchRoute(route.path)
}

func dispatchRoute(_ route: AppRoute, keepSubroutes: Bool) {
dispatchRoute(route.path, keepSubroutes: keepSubroutes)
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="sHK-wP-PBS"/>
<viewControllerLayoutGuide type="bottom" id="Tlu-nZ-QcN"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
Expand Down
10 changes: 6 additions & 4 deletions Example/MonarchRouterExample/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="2He-Z9-tZI">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="2He-Z9-tZI">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Mock View Controller-->
<scene sceneID="2xn-LS-cZM">
<objects>
<viewController id="2He-Z9-tZI" customClass="MockViewController" customModule="MonarchRouterExample" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="tNb-yJ-bpj"/>
<viewControllerLayoutGuide type="bottom" id="deW-3w-6h8"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="bZz-s6-b3s">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
Expand All @@ -38,10 +41,9 @@
<constraint firstItem="mCz-mt-UBW" firstAttribute="centerY" secondItem="bZz-s6-b3s" secondAttribute="centerY" multiplier="1.3" id="1x4-Zk-1dR"/>
<constraint firstItem="mCz-mt-UBW" firstAttribute="centerX" secondItem="bZz-s6-b3s" secondAttribute="centerX" id="I9v-rK-sAc"/>
<constraint firstItem="vDH-i9-avN" firstAttribute="centerX" secondItem="bZz-s6-b3s" secondAttribute="centerX" id="Ska-UL-Xa6"/>
<constraint firstItem="vDH-i9-avN" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="vty-1G-c4M" secondAttribute="leading" constant="20" id="UQe-RM-2ft"/>
<constraint firstItem="vDH-i9-avN" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="bZz-s6-b3s" secondAttribute="leading" constant="20" id="UQe-RM-2ft"/>
<constraint firstItem="vDH-i9-avN" firstAttribute="centerY" secondItem="bZz-s6-b3s" secondAttribute="centerY" multiplier="0.7" id="kbe-3Y-ui0"/>
</constraints>
<viewLayoutGuide key="safeArea" id="vty-1G-c4M"/>
</view>
<connections>
<outlet property="button" destination="mCz-mt-UBW" id="2RM-0F-5fQ"/>
Expand Down
14 changes: 7 additions & 7 deletions Example/MonarchRouterExample/EndpointBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,37 +25,37 @@ func buildEndpoint(for route: AppRoute, routeDispatcher: ProvidesRouteDispatch)

switch route {
case .login:
vc.configure(title: "Login screen", buttonTitle: "Login", buttonAction: {
vc.configure(title: "Login screen", didAppearAction: { routeDispatcher.dispatchRoute(route) }, buttonTitle: "Login", buttonAction: {
routeDispatcher.dispatchRoute(AppRoute.onboarding(name: "USERNAME"))
}, backgroundColor: .purple)

case .first:
vc.configure(title: "Main screen", buttonTitle: "Detail", buttonAction: {
vc.configure(title: "Main screen", didAppearAction: { routeDispatcher.dispatchRoute(route) }, buttonTitle: "Detail", buttonAction: {
routeDispatcher.dispatchRoute(AppRoute.firstDetail)
}, backgroundColor: .magenta)

case .firstDetail:
vc.configure(title: "First detail", buttonTitle: "Parametrized Detail", buttonAction: {
vc.configure(title: "First detail", didAppearAction: { routeDispatcher.dispatchRoute(route) }, buttonTitle: "Parametrized Detail", buttonAction: {
routeDispatcher.dispatchRoute(AppRoute.firstDetailParametrized(id: "-firstDetail"))
}, backgroundColor: .magenta)

case .second:
vc.configure(title: "Second screen", buttonTitle: "Second detail", buttonAction: {
vc.configure(title: "Second screen", didAppearAction: { routeDispatcher.dispatchRoute(route) }, buttonTitle: "Second detail", buttonAction: {
routeDispatcher.dispatchRoute(AppRoute.secondDetail)
}, backgroundColor: .orange)

case .secondDetail:
vc.configure(title: "Second detail", buttonTitle: "First detail", buttonAction: {
vc.configure(title: "Second detail", didAppearAction: { routeDispatcher.dispatchRoute(route) }, buttonTitle: "First detail", buttonAction: {
routeDispatcher.dispatchRoute(AppRoute.firstDetail)
}, backgroundColor: .orange)

case .fifth:
vc.configure(title: "Fifth screen", buttonTitle: "Modal", buttonAction: {
vc.configure(title: "Fifth screen", didAppearAction: { routeDispatcher.dispatchRoute(route) }, buttonTitle: "Modal", buttonAction: {
routeDispatcher.dispatchRoute(AppRoute.modalParametrized(id: "-someModal"))
}, backgroundColor: .darkGray)

case .modal:
vc.configure(title: "Modal screen", buttonTitle: "Fifth", buttonAction: {
vc.configure(title: "Modal screen", didAppearAction: { routeDispatcher.dispatchRoute(route) }, buttonTitle: "Fifth", buttonAction: {
routeDispatcher.dispatchRoute(AppRoute.fifth)
}, backgroundColor: .blue)

Expand Down
2 changes: 1 addition & 1 deletion Example/MonarchRouterExample/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<string>0.9.3</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
Expand Down
12 changes: 11 additions & 1 deletion Example/MonarchRouterExample/MockViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ class MockViewController: UIViewController
@IBOutlet weak var button: UIButton!

/// Call this method to configure VC right after the initialization or getting the `RouteParameters`.
func configure(title: String, buttonTitle: String?, buttonAction: (()->())?, backgroundColor: UIColor)
func configure(title: String, didAppearAction: (()->())?, buttonTitle: String?, buttonAction: (()->())?, backgroundColor: UIColor)
{
self.didAppearAction = didAppearAction
self.titleString = title
self.buttonTitleString = buttonTitle
self.buttonAction = buttonAction
Expand All @@ -26,6 +27,7 @@ class MockViewController: UIViewController
applyConfig()
}

private var didAppearAction: (()->())?
private var titleString: String!
private var buttonTitleString: String?
private var buttonAction: (()->())?
Expand Down Expand Up @@ -53,6 +55,14 @@ class MockViewController: UIViewController

self.view.backgroundColor = backgroundColor
}


override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

didAppearAction?()
}


@IBAction func buttonAction(_ sender: Any) {
buttonAction?()
Expand Down
Loading

0 comments on commit 49beaee

Please sign in to comment.