├── DarwinNativeRouter.xcodeproj
├── xcuserdata
│ └── yuri_jou.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── DarwinNativeRouter.xcscheme
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── yuri_jou.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── project.pbxproj
├── DarwinNativeRouter
├── ViewController.h
├── AppDelegate.h
├── main.m
├── DarwinNativeRouter
│ ├── DarwinNativeRouter.h
│ ├── UIViewController+DNRouterExtra.h
│ ├── UIViewController+DNRouterExtra.m
│ ├── DNRouterCenter.h
│ ├── DNRouter.h
│ ├── DNRouter.m
│ └── DNRouterCenter.m
├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── ViewController.m
├── Info.plist
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
└── AppDelegate.m
├── DarwinNativeRouterTests
├── Info.plist
└── DarwinNativeRouterTests.m
├── DarwinNativeRouterUITests
├── Info.plist
└── DarwinNativeRouterUITests.m
└── README.md
/DarwinNativeRouter.xcodeproj/xcuserdata/yuri_jou.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/DarwinNativeRouter.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/DarwinNativeRouter.xcodeproj/project.xcworkspace/xcuserdata/yuri_jou.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oenius/DarwinNativeRouter/HEAD/DarwinNativeRouter.xcodeproj/project.xcworkspace/xcuserdata/yuri_jou.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/DarwinNativeRouter/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // DarwinNativeRouter
4 | //
5 | // Created by YURI_JOU on 16/3/28.
6 | // Copyright © 2016年 oenius. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "DNRouter.h"
12 |
13 | @interface ViewController : UIViewController
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/DarwinNativeRouter/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // DarwinNativeRouter
4 | //
5 | // Created by YURI_JOU on 16/3/28.
6 | // Copyright © 2016年 oenius. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/DarwinNativeRouter/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // DarwinNativeRouter
4 | //
5 | // Created by YURI_JOU on 16/3/28.
6 | // Copyright © 2016年 oenius. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/DarwinNativeRouter/DarwinNativeRouter/DarwinNativeRouter.h:
--------------------------------------------------------------------------------
1 | //
2 | // DarwinNativeRouter.h
3 | // DarwinNativeRouter
4 | //
5 | // Created by YURI_JOU on 16/4/1.
6 | // Copyright © 2016年 oenius. All rights reserved.
7 | //
8 |
9 | #ifndef DarwinNativeRouter_h
10 | #define DarwinNativeRouter_h
11 |
12 | #import "DNRouter.h"
13 | #import "DNRouterCenter.h"
14 | #import "UIViewController+DNRouterExtra.h"
15 |
16 | #endif /* DarwinNativeRouter_h */
17 |
--------------------------------------------------------------------------------
/DarwinNativeRouter/DarwinNativeRouter/UIViewController+DNRouterExtra.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewController+DNRouterExtra.h
3 | // DarwinNativeRouter
4 | //
5 | // Created by YURI_JOU on 16/3/28.
6 | // Copyright © 2016年 oenius. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIViewController (DNRouterExtra)
12 |
13 | @property (nonatomic, assign)BOOL dn_pushAnimationNeeded;
14 | @property (nonatomic, assign)BOOL dn_popAnimationNeeded;
15 |
16 | - (void)dn_viewDidLoadQuery:(NSDictionary *)queryItems;
17 | - (void)dn_viewDidLoadQueryId:(NSString *)qid;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/DarwinNativeRouter/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/DarwinNativeRouterTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/DarwinNativeRouterUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/DarwinNativeRouter.xcodeproj/xcuserdata/yuri_jou.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | DarwinNativeRouter.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 1A0F1E8C1CA940C0003013D4
16 |
17 | primary
18 |
19 |
20 | 1A0F1EA51CA940C0003013D4
21 |
22 | primary
23 |
24 |
25 | 1A0F1EB01CA940C0003013D4
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/DarwinNativeRouterTests/DarwinNativeRouterTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // DarwinNativeRouterTests.m
3 | // DarwinNativeRouterTests
4 | //
5 | // Created by YURI_JOU on 16/3/28.
6 | // Copyright © 2016年 oenius. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DarwinNativeRouterTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation DarwinNativeRouterTests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 | // Put setup code here. This method is called before the invocation of each test method in the class.
20 | }
21 |
22 | - (void)tearDown {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | [super tearDown];
25 | }
26 |
27 | - (void)testExample {
28 | // This is an example of a functional test case.
29 | // Use XCTAssert and related functions to verify your tests produce the correct results.
30 | }
31 |
32 | - (void)testPerformanceExample {
33 | // This is an example of a performance test case.
34 | [self measureBlock:^{
35 | // Put the code you want to measure the time of here.
36 | }];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/DarwinNativeRouter/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // DarwinNativeRouter
4 | //
5 | // Created by YURI_JOU on 16/3/28.
6 | // Copyright © 2016年 oenius. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "DNRouter.h"
11 | #import "UIViewController+DNRouterExtra.h"
12 |
13 | @interface ViewController ()
14 |
15 | @end
16 |
17 | @implementation ViewController
18 |
19 | - (void)viewDidLoad
20 | {
21 | [super viewDidLoad];
22 | }
23 |
24 | - (IBAction)handleClick:(id)sender
25 | {
26 |
27 | }
28 |
29 | - (void)dn_viewDidLoadQuery:(NSDictionary *)queryItems
30 | {
31 |
32 | }
33 |
34 | - (void)dn_viewDidLoadQueryId:(NSString *)qid
35 | {
36 |
37 | }
38 |
39 | - (IBAction)nameAction:(id)sender
40 | {
41 | [[DNRouter router]redirect:@"MAIN"];
42 | }
43 |
44 | - (IBAction)staticActionWithParams:(id)sender
45 | {
46 | [[DNRouter router]open:@"/home/home/home"];
47 | }
48 |
49 | - (IBAction)dynaimcActionWithParams:(id)sender
50 | {
51 | [[DNRouter router]open:@"/user/10238372?lalal=88&sss=999&rr=11"];
52 | }
53 |
54 | - (IBAction)mixActionWithParams:(id)sender
55 | {
56 | [[DNRouter router]open:@"/home/user/10238372"];
57 | }
58 |
59 | @end
60 |
--------------------------------------------------------------------------------
/DarwinNativeRouter/DarwinNativeRouter/UIViewController+DNRouterExtra.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewController+DNRouterExtra.m
3 | // DarwinNativeRouter
4 | //
5 | // Created by YURI_JOU on 16/3/28.
6 | // Copyright © 2016年 oenius. All rights reserved.
7 | //
8 |
9 | #import "UIViewController+DNRouterExtra.h"
10 |
11 | #import
12 |
13 | static const void *pushAnimated = &pushAnimated;
14 | static const void *popAnimated = &popAnimated;
15 |
16 | @implementation UIViewController (DNRouterExtra)
17 | @dynamic dn_pushAnimationNeeded, dn_popAnimationNeeded;
18 |
19 | - (BOOL)dn_popAnimationNeeded
20 | {
21 | return [objc_getAssociatedObject(self, popAnimated) boolValue];
22 | }
23 |
24 | - (BOOL)dn_pushAnimationNeeded
25 | {
26 | return [objc_getAssociatedObject(self, pushAnimated) boolValue];
27 | }
28 |
29 | - (void)setDn_popAnimationNeeded:(BOOL)dn_popAnimationNeeded
30 | {
31 | objc_setAssociatedObject(self, popAnimated, @(dn_popAnimationNeeded), OBJC_ASSOCIATION_ASSIGN);
32 | }
33 |
34 | - (void)setDn_pushAnimationNeeded:(BOOL)dn_pushAnimationNeeded
35 | {
36 | objc_setAssociatedObject(self, pushAnimated, @(dn_pushAnimationNeeded), OBJC_ASSOCIATION_ASSIGN);
37 | }
38 |
39 | - (void)dn_viewDidLoadQuery:(NSDictionary *)queryItems{}
40 | - (void)dn_viewDidLoadQueryId:(NSString *)qid{}
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/DarwinNativeRouter/DarwinNativeRouter/DNRouterCenter.h:
--------------------------------------------------------------------------------
1 | //
2 | // DNRouterCenter.h
3 | // DarwinNativeRouter
4 | //
5 | // Created by YURI_JOU on 16/3/29.
6 | // Copyright © 2016年 oenius. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef NS_ENUM(NSInteger, DNActionBehavior)
12 | {
13 | DNActionPopBehavior,
14 | DNActionPopToRootBehavior,
15 | DNActionAttachedBehavior,
16 | DNActionDynamicUndefineBehavior
17 | };
18 |
19 | @interface DNAction : NSObject
20 |
21 | @property (nonatomic, assign)DNActionBehavior behavior;
22 | @property (nonatomic, strong)NSDictionary *queryItems;
23 |
24 | @property (nonatomic, copy)NSString *queryId;
25 |
26 | @property (nonatomic, copy) UIViewController *(^controller)(void);
27 | @property (nonatomic, copy) void *(^action)(UIViewController *controller);
28 |
29 | @end
30 |
31 | @interface DNRouterCenter : NSObject
32 |
33 | @property (nonatomic, copy)NSString *scheme;
34 |
35 | + (instancetype)defaultCenter;
36 |
37 | - (void)addName:(NSString *)name
38 | path:(NSString *)path
39 | controller:(__kindof UIViewController *(^)(void))controller
40 | action:(void(^)(__kindof UIViewController *controller))action;
41 |
42 | - (DNAction *)actionOfName:(NSString *)name;
43 | - (NSArray *)actionsOfPath:(NSString *)path;
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/DarwinNativeRouterUITests/DarwinNativeRouterUITests.m:
--------------------------------------------------------------------------------
1 | //
2 | // DarwinNativeRouterUITests.m
3 | // DarwinNativeRouterUITests
4 | //
5 | // Created by YURI_JOU on 16/3/28.
6 | // Copyright © 2016年 oenius. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DarwinNativeRouterUITests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation DarwinNativeRouterUITests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 |
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 |
22 | // In UI tests it is usually best to stop immediately when a failure occurs.
23 | self.continueAfterFailure = NO;
24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
25 | [[[XCUIApplication alloc] init] launch];
26 |
27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
28 | }
29 |
30 | - (void)tearDown {
31 | // Put teardown code here. This method is called after the invocation of each test method in the class.
32 | [super tearDown];
33 | }
34 |
35 | - (void)testExample {
36 | // Use recording to get started writing UI tests.
37 | // Use XCTAssert and related functions to verify your tests produce the correct results.
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/DarwinNativeRouter/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | CFBundleURLTypes
40 |
41 |
42 | CFBundleURLName
43 | com.beiyunbang.doctor
44 | CFBundleURLSchemes
45 |
46 | DNR
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/DarwinNativeRouter/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/DarwinNativeRouter/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // DarwinNativeRouter
4 | //
5 | // Created by YURI_JOU on 16/3/28.
6 | // Copyright © 2016年 oenius. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "DarwinNativeRouter.h"
11 |
12 | @interface AppDelegate ()
13 |
14 | @end
15 |
16 | @implementation AppDelegate
17 |
18 |
19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
20 |
21 | //Do initialize the router
22 | [self applicationLoadRouter];
23 |
24 | return YES;
25 | }
26 |
27 | - (void)applicationLoadRouter
28 | {
29 | [DNRouter routerWithName:@"MAIN" path:@"/home" controller:^__kindof UIViewController *{
30 | UIViewController *controller = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"kMainBoard"];
31 | return controller;
32 | } action:^(__kindof UIViewController *controller) {
33 | [(UINavigationController *)self.window.rootViewController pushViewController:controller animated:NO];
34 | }];
35 |
36 | [DNRouter routerWithName:@"PROFILE" path:@"/user/:id" controller:^__kindof UIViewController *{
37 | UIViewController *controller = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"kMainBoard"];
38 | return controller;
39 | } action:^(__kindof UIViewController *controller) {
40 | [(UINavigationController *)self.window.rootViewController pushViewController:controller animated:NO];
41 | }];
42 | }
43 |
44 | - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options
45 | {
46 | if([[DNRouter router]canOpen:url.absoluteString])
47 | {
48 | [[DNRouter router]open:url.absoluteString];
49 | return YES;
50 | }
51 | return NO;
52 | }
53 |
54 | @end
55 |
--------------------------------------------------------------------------------
/DarwinNativeRouter/DarwinNativeRouter/DNRouter.h:
--------------------------------------------------------------------------------
1 | //
2 | // DNRouter.h
3 | // DarwinNativeRouter
4 | //
5 | // Created by YURI_JOU on 16/3/28.
6 | // Copyright © 2016年 oenius. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | ///---------------
12 | /// @name DNRouter
13 | ///---------------
14 |
15 | @interface DNRouter : NSObject
16 |
17 | ///---------------
18 | /// @name DarwinNativeRouter handling
19 | ///---------------
20 |
21 | /**
22 | Returns the default singleton instance.
23 | */
24 | + (instancetype)router;
25 |
26 | /**
27 | If not set, then uses the first scheme value setted in info.plist.
28 | Returns a entirely new router instance.
29 | */
30 | + (instancetype)registNativeWithScheme:(NSString *)scheme;
31 |
32 | /**
33 | Just like the router of 404 & index.html action in the web application.
34 | Default router action will be executed when just routed to the scheme.
35 | notFound router action will be executed when the path not matched.
36 | */
37 | + (instancetype)defaultRouterWithController:(__kindof UIViewController *(^)(void))controller
38 | action:(void(^)(__kindof UIViewController *controller)) action;
39 |
40 | + (instancetype)notFoundRouterWithController:(__kindof UIViewController *(^)(void))controller
41 | action:(void(^)(__kindof UIViewController *controller)) action;
42 |
43 | ///---------------
44 | /// @name DarwinNativeRouter path & action mapping settings
45 | ///---------------
46 |
47 | /**
48 | @param path The path route formate supports static & dynamic uri. Static example: '/profile/'. Dynamic example: '/user/:userId/', and regix also supported.
49 | */
50 | + (instancetype)routerWithName:(NSString *)name
51 | path:(NSString *)path
52 | controller:(__kindof UIViewController *(^)(void))controller
53 | action:(void(^)(__kindof UIViewController *controller)) action;
54 |
55 | /**
56 | @param path The path route formate supports static & dynamic uri. Static example: '/profile/'. Dynamic example: '/user/1991/profile/'. Also regix supported.
57 | @param navigationController The navigationController to support './', '../', '/'.
58 | */
59 | + (instancetype)routerWithName:(NSString *)name
60 | path:(NSString *)path
61 | navigationController:(UINavigationController *)navigationController
62 | controller:(__kindof UIViewController *(^)(void))controller
63 | action:(void(^)(__kindof UIViewController *controller))action;
64 |
65 | ///---------------
66 | /// @name DarwinNativeRouter router behavior
67 | ///---------------
68 |
69 | /**
70 | @param path supports './', '../', '/'.
71 | */
72 | - (__kindof UIViewController *)open:(NSString *)path;
73 |
74 | /**
75 | Return YES when can route to path.
76 | */
77 | - (BOOL)canOpen:(NSString *)path;
78 |
79 | /**
80 | @param name execute the action map the name.
81 | */
82 | - (__kindof UIViewController *)redirect:(NSString *)name;
83 |
84 | /**
85 | Return YES when can route to name.
86 | */
87 | - (BOOL)canRedirect:(NSString *)name;
88 |
89 | @end
90 |
91 |
92 |
--------------------------------------------------------------------------------
/DarwinNativeRouter.xcodeproj/xcuserdata/yuri_jou.xcuserdatad/xcschemes/DarwinNativeRouter.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
43 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
74 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
95 |
101 |
102 |
103 |
104 |
106 |
107 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/DarwinNativeRouter/DarwinNativeRouter/DNRouter.m:
--------------------------------------------------------------------------------
1 | //
2 | // DNRouter.m
3 | // DarwinNativeRouter
4 | //
5 | // Created by YURI_JOU on 16/3/28.
6 | // Copyright © 2016年 oenius. All rights reserved.
7 | //
8 |
9 | #import "DNRouter.h"
10 | #import "DNRouterCenter.h"
11 | #import "UIViewController+DNRouterExtra.h"
12 |
13 | @interface DNRouter()
14 |
15 | @property (nonatomic, copy) NSString *scheme;
16 | @property (nonatomic, strong)UINavigationController *navigationController;
17 |
18 | @end
19 |
20 |
21 | @implementation DNRouter
22 |
23 | + (instancetype)router
24 | {
25 | static DNRouter *router;
26 | static dispatch_once_t onceToken;
27 |
28 | dispatch_once(&onceToken, ^{
29 | router = [[self.class alloc]init];
30 | });
31 |
32 | return router;
33 | }
34 |
35 | + (instancetype)registNativeWithScheme:(NSString *)scheme
36 | {
37 | [DNRouter router].scheme = scheme;
38 | return [DNRouter router];
39 | }
40 |
41 | + (instancetype)defaultRouterWithController:(__kindof UIViewController *(^)(void))controller
42 | action:(void(^)(__kindof UIViewController *controller))action
43 | {
44 | DNRouter *router = [DNRouter router];
45 | return router;
46 | }
47 |
48 | + (instancetype)notFoundRouterWithController:(__kindof UIViewController *(^)(void))controller
49 | action:(void(^)(__kindof UIViewController *controller))action
50 | {
51 |
52 | DNRouter *router = [DNRouter router];
53 | return router;
54 | }
55 |
56 | + (instancetype)routerWithName:(NSString *)name
57 | path:(NSString *)path
58 | controller:(__kindof UIViewController *(^)(void))controller
59 | action:(void(^)(__kindof UIViewController *controller)) action;
60 | {
61 |
62 | [[DNRouterCenter defaultCenter]addName:name path:path controller:controller action:action];
63 | return [DNRouter router];
64 | }
65 |
66 | + (instancetype)routerWithName:(NSString *)name
67 | path:(NSString *)path
68 | navigationController:(UINavigationController *)navigationController
69 | controller:(__kindof UIViewController *(^)(void))controller
70 | action:(void(^)(__kindof UIViewController *controller))action
71 | {
72 | [DNRouter router].navigationController = navigationController;
73 | [[DNRouterCenter defaultCenter]addName:name path:path controller:controller action:action];
74 | return [DNRouter router];
75 | }
76 |
77 | - (instancetype)init
78 | {
79 | self = [super init];
80 | if(self)
81 | {
82 | [DNRouterCenter defaultCenter].scheme = self.scheme;
83 | }
84 | return self;
85 | }
86 |
87 | - (__kindof UIViewController *)open:(NSString *)path
88 | {
89 | NSArray *actions = [[DNRouterCenter defaultCenter]actionsOfPath:path];
90 |
91 | if(!actions) return nil;
92 | for(DNAction *action in actions)
93 | {
94 | if(action.behavior == DNActionAttachedBehavior)
95 | {
96 | if(action.action)
97 | {
98 | UIViewController *controller = action.controller();
99 | if([controller respondsToSelector:@selector(dn_viewDidLoadQuery:)])
100 | {
101 | [controller dn_viewDidLoadQuery:action.queryItems];
102 | }
103 |
104 | if([controller respondsToSelector:@selector(dn_viewDidLoadQueryId:)])
105 | {
106 | [controller dn_viewDidLoadQueryId:action.queryId];
107 | }
108 |
109 | if(controller && [controller isKindOfClass:[UIViewController class]]) action.action(controller);
110 | }
111 | }
112 |
113 | if(action.behavior == DNActionPopBehavior && self.navigationController)
114 | {
115 | [self.navigationController popViewControllerAnimated:self.navigationController.topViewController.dn_popAnimationNeeded];
116 | }
117 |
118 | if(action.behavior == DNActionPopToRootBehavior && self.navigationController)
119 | {
120 | [self.navigationController popToRootViewControllerAnimated:NO];
121 | }
122 | }
123 |
124 | return nil;
125 | }
126 |
127 | - (BOOL)canOpen:(NSString *)path
128 | {
129 | NSArray *actions = [[DNRouterCenter defaultCenter]actionsOfPath:path];
130 | if(!actions) return NO;
131 | return YES;
132 | }
133 |
134 | - (__kindof UIViewController *)redirect:(NSString *)name
135 | {
136 | DNAction *action = [[DNRouterCenter defaultCenter]actionOfName:name];
137 | if(!action) return nil;
138 | UIViewController *controller = action.controller();
139 | if(controller && [controller isKindOfClass:[UIViewController class]]) action.action(controller);
140 | return controller;
141 | }
142 |
143 | - (BOOL)canRedirect:(NSString *)name;
144 | {
145 | if([[DNRouterCenter defaultCenter]actionOfName:name]) return YES;
146 | return NO;
147 | }
148 |
149 | - (NSString *)scheme
150 | {
151 | if(!_scheme)
152 | {
153 | NSArray *urls = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleURLTypes"];
154 | id values = urls.firstObject;
155 | if(values && [values isKindOfClass:[NSDictionary class]])
156 | {
157 | _scheme = [[values objectForKey:@"CFBundleURLSchemes"] firstObject];
158 | }
159 | }
160 | return _scheme;
161 | }
162 |
163 | @end
164 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | *PS* 感谢大家的关注,由于我本想开源4个库,除了router, 另外三个分别是native dispatcher, web dispatcher 和 react dispatcher , 所以router 对native dispatcher 有了库依赖,为了共同学习,我把router单独分离成pod,再次感谢大家的关注,欢迎叫router更完善。best regards.
2 |
3 | # 如何优雅的实现界面跳转 之 统跳协议 - DarwinNativeRouter
4 |
5 | ## 预热 - 我要解决的问题
6 |
7 | > 首先我还是要推荐Gaosboy的这篇文章[解耦神器 —— 统跳协议和Rewrite引擎](http://pingguohe.net/2015/11/24/Navigator-and-Rewrite.html)
8 | > 文章中,介绍了天猫app,基于文件配置和uri的页面跳转。这大大增加了app端的灵活性, 而这种实现很类似今天的前端或后端开发中的 静态路由 和 动态路由协议。
9 | > 除了天猫,在很多的客户端架构的文章中,路由解耦的案例并不不少见,如[携程移动App架构优化之旅](https://mp.weixin.qq.com/s?__biz=MzA3ODg4MDk0Ng==&mid=403009403&idx=1&sn=d19264fa1d06b9c5a9dfb1d192a0ed8e&scene=1&srcid=0401q08nZugjahvHG8rIXA3D&key=710a5d99946419d9421e8fbc5fb565c3a91aaaba22b5db9dffc9bcfae33aa18f533fbe82c6c570fec3720d82be5b9b5a&ascene=0&uin=MTMzODgyNTU%3D&devicetype=iMac+MacBookPro10%2C1+OSX+OSX+10.11+build(15A282b)&version=11000004&pass_ticket=IbzhLj2Kxa98XTnVDWywF6o6dyAlCik592Btwh3yT4A%3D)
10 | > [蘑菇街App的组件化之路](https://mp.weixin.qq.com/s?__biz=MzA3ODg4MDk0Ng==&mid=402696366&idx=1&sn=ba8cbd75849b9657175c4b25bb0ac5b5&scene=1&srcid=0401oAmP7sfKiXI2di3pJuOk&key=710a5d99946419d91e680351171de6fada2f6c71eaae2e235c5d4c37c97363d6a9d3cd45dd9ab9cdcccf2a0e701d01c5&ascene=0&uin=MTMzODgyNTU%3D&devicetype=iMac+MacBookPro10%2C1+OSX+OSX+10.11+build(15A282b)&version=11000004&pass_ticket=IbzhLj2Kxa98XTnVDWywF6o6dyAlCik592Btwh3yT4A%3D)
11 | > 原生路由协议, 其实两年前就有了类似的实现。比如900+Star的[HHRouter](https://github.com/Huohua/HHRouter),而作者是当时还在布丁动画工作的Light。2015年我有幸见到本人,人很nice,并真是全栈。
12 | > DarwinNativeRouter 在接口设计上,很大程度上的参考了现有的react路由协议 react router。并且对原生跳转方式保留很大的可扩展性。所以我的初衷 DarwinNativeRouter 是一个足够轻量级的框架。Light & Flexible。
13 |
14 | ## 全局路由协议能解决的问题
15 |
16 | ### 错中复杂的Controller的跳转依赖
17 |
18 | > 在iOS的世界里,传统的Controller跳转方式, A 跳转 B, 则 A 必须持有 B 的对象。 而在app长大的过程中, 势必会造成 A -> B , B -> C, A -> C D, E, F...
19 | > 从而产生复杂的依赖链。全局的Router 使 A 不必依赖于 特定的 Controller 便可以实现跳转。
20 |
21 | 如下面跳转:
22 |
23 | We Always Do:
24 |
25 | ```
26 |
27 | UIViewController *personal = [UIViewController new];
28 | personal.userId = @"10238372";
29 | [self.navigationController pushViewController:personal animated:NO];
30 |
31 |
32 |
33 | ```
34 |
35 | Router Code:
36 |
37 | ```
38 |
39 | [[DNRouter router]open:@"./user/10238372/profile"];
40 |
41 | ```
42 |
43 | 又比如我们要在navigationController根路径跳转
44 |
45 | We Always Do:
46 |
47 | ```
48 | [self.navigationController popToRootViewControllerAnimated:NO];
49 | UIViewController *personal = [UIViewController new];
50 | personal.userId = @"10238372";
51 | [self.navigationController pushViewController:personal animated:YES];
52 |
53 | ```
54 |
55 | Router Code:
56 |
57 | ```
58 |
59 | [[DNRouter router]open:@"/user/10238372/profile"];
60 |
61 | ```
62 |
63 | ### 推送通知,点击打开指定页面
64 |
65 | > 对于这种需求, 相信,目前最多的实现应该是两种, 一种的传参的Url, 而另一种,是传递int类型,并通过类似switch case对参数值的硬编码,实现跳转逻辑。
66 | > 我是很反感第二种的跳转方式, 1. int毫无疑义, 只能硬解释。 2. 跳转的页面有限。 当然如果url采用硬编码, 也是跳转有限的。
67 | > 而有了router,一切不一样。
68 |
69 | 1. 从didFinishLaunchingWithOptions 和 didReceiveRemoteNotification捕获payload
70 |
71 | 2. 跳用Router
72 |
73 | Somethings we may do:
74 |
75 | ```
76 | switch (type) {
77 | case 1001:
78 | //jumping code
79 | break;
80 |
81 | case 1002:
82 | //jumping code
83 | break;
84 | case 1003:
85 | //jumping code
86 | break;
87 | case 1004:
88 | //jumping code
89 | break;
90 |
91 | default:
92 | break;
93 | }
94 | ```
95 |
96 | Now we need do:
97 | ```
98 | if([[DNRouter router]canOpen:url.absoluteString]) [[DNRouter router]open:url.absoluteString];
99 |
100 | ```
101 | ### app间通讯 及 deeplink
102 |
103 | > Router 可以轻松handle deeplink。 deeplink 即: 从safari打开app的指定页面。 这方面做得比较好的, 如新浪微博的app, 在点击对应的新浪微博热点 条目时, 就发生了跳转,并跳到了条目详情。
104 | > Router, 同样可以被用作 app 间通讯, 和 deeplink 的原理相同。uri的通讯方式,被认为是最简单的app间通讯。 如我们常常使用的微信分享,配置的 scheme 就是用来做跳转和通讯的。
105 |
106 | Router Code
107 |
108 | ```
109 |
110 | - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options
111 | {
112 | if([[DNRouter router]canOpen:url.absoluteString])
113 | {
114 | [[DNRouter router]open:url.absoluteString];
115 | return YES;
116 | }
117 | return NO;
118 | }
119 |
120 | ```
121 | ### 一致的行为处理, Hybrid & React Native
122 |
123 | > 有了Router, 你可以使这些跳转 有一致的行为。
124 |
125 | ## DarwinNativeRouter 特性
126 |
127 |
128 | ### 静态路由 /user
129 |
130 | ```
131 | [DNRouter routerWithName:@"profile" path:@"/user"
132 | navigationController:(UINavigationController *)self.window.rootViewController
133 | controller:^__kindof UIViewController *{
134 |
135 | UIViewController *controller = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"kMainBoard"];
136 | return controller;
137 |
138 | } action:^(__kindof UIViewController *controller) {
139 |
140 | [DNDispatcher dispatcher].defaultNavigationController.animation(YES).pushViewController(controller);
141 |
142 | }];
143 |
144 | ```
145 |
146 |
147 | ### 动态路由 /user/:id
148 |
149 | ```
150 | [DNRouter routerWithName:@"profile" path:@"/user/:id"
151 | navigationController:(UINavigationController *)self.window.rootViewController
152 | controller:^__kindof UIViewController *{
153 |
154 | UIViewController *controller = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"kMainBoard"];
155 | return controller;
156 |
157 | } action:^(__kindof UIViewController *controller) {
158 |
159 | [DNDispatcher dispatcher].defaultNavigationController.animation(YES).pushViewController(controller);
160 | // 希望大家注意下动画的设置,若animation设为YES, 容易造成animation system的混乱,需要保证最后一个push的前的所有controller的动画为NO.
161 |
162 | }];
163 |
164 | ```
165 | ### 更方便的跳转,名称跳转 name jumping
166 |
167 | ```
168 | [[DNRouter router]redirect:@"profile"];
169 |
170 | ```
171 |
172 | ### 相对路径跳转
173 |
174 | ```
175 | //跟路径
176 | [[DNRouter router]open:@"/user"];
177 |
178 | //当前路径
179 | [[DNRouter router]open:@"./user"];
180 |
181 | //上一级
182 | [[DNRouter router]open:@"../user"];
183 |
184 | ```
185 | ### 易扩展, 自定义跳转 action
186 |
187 | ```
188 | [DNRouter routerWithName:@"profile" path:@"/user/:id"
189 | navigationController:(UINavigationController *)self.window.rootViewController
190 | controller:^__kindof UIViewController *{
191 |
192 | UIViewController *controller = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"kMainBoard"];
193 | return controller;
194 |
195 | } action:^(__kindof UIViewController *controller) {
196 |
197 | [DNDispatcher dispatcher].defaultNavigationController.animation(YES).pushViewController(controller);
198 | // 希望大家注意下动画的设置,若animation设为YES, 容易造成animation system的混乱,需要保证最后一个push的前的所有controller的动画为NO.
199 |
200 | }];
201 |
202 | ```
203 | ### 默认行为,及 异常处理,index & 404
204 |
205 | ```
206 | // index page
207 | [DNRouter defaultRouterWithController:^__kindof UIViewController *{
208 |
209 | } action:^(__kindof UIViewController *controller) {
210 |
211 | }];
212 |
213 | // 404 page
214 | [DNRouter notFoundRouterWithController:^__kindof UIViewController *{
215 |
216 | } action:^(__kindof UIViewController *controller) {
217 |
218 | }];
219 |
220 | ```
221 |
222 | ## 后言
223 |
224 | DarwinNativeRouter 现在还没有到1.0版本,还有很多可以想象的东西,欢迎让他更加完善,和提pr。
225 | [DarwinNativeRouter's Github](https://github.com/oenius/DarwinNativeRouter)
226 |
227 |
228 | @author Jou [Email](jou@oenius.com) [Weibo](http://weibo.com/monfur) or [Github](https://github.com/oenius)
229 |
--------------------------------------------------------------------------------
/DarwinNativeRouter/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
48 |
59 |
70 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/DarwinNativeRouter/DarwinNativeRouter/DNRouterCenter.m:
--------------------------------------------------------------------------------
1 | //
2 | // DNRouterCenter.m
3 | // DarwinNativeRouter
4 | //
5 | // Created by YURI_JOU on 16/3/29.
6 | // Copyright © 2016年 oenius. All rights reserved.
7 | //
8 |
9 | #define DN_REGEX_SCHEME @"^([\\w- .]+)"
10 | #define DN_REGEX_SCHEME_PREFIX @"^([\\w- .]+)(://)"
11 |
12 | #define DN_REGEX_STATIC_PATH @"^([\\w- .]+)"
13 | #define DN_REGEX_DYNAMIC_PATH @"^(/)([\\w- .]+)(/:)"
14 | #define DN_REGEX_DYNAMIC_VALUE_PATH @"(:[\\w- .]+)"
15 |
16 | #define DN_REGEX_DYNAMIC_VALUE_SUFFIX @"([\\w- .]+)$"
17 |
18 | #define DN_REGEX_PARAMS_SUFFIX @"(\\?[\\w- .&=]+)$"
19 | #define DN_REGEX_PARAMS_UNIT @"([\\w- ]+)(=)([\\w- ]+)$"
20 |
21 | #import "DNRouterCenter.h"
22 |
23 | @implementation DNAction
24 | @end
25 |
26 | @interface DNRouterCenter()
27 |
28 | @property (nonatomic, strong)NSMutableArray *pathPatterns;
29 |
30 | @property (nonatomic, strong)NSMutableDictionary *nameActionMapping;
31 | @property (nonatomic, strong)NSMutableDictionary *nameControllerMapping;
32 |
33 | @property (nonatomic, strong)NSMutableDictionary *pathActionMapping;
34 | @property (nonatomic, strong)NSMutableDictionary *pathControllerMapping;
35 |
36 | @end
37 |
38 | @implementation DNRouterCenter
39 |
40 | + (instancetype)defaultCenter
41 | {
42 | static DNRouterCenter *defaultCenter;
43 | static dispatch_once_t onceToken;
44 |
45 | dispatch_once(&onceToken, ^{
46 | defaultCenter = [[self.class alloc]init];
47 | });
48 |
49 | return defaultCenter;
50 | }
51 |
52 | - (NSMutableArray *)pathPatterns
53 | {
54 | if(!_pathPatterns)
55 | {
56 | _pathPatterns = [@[] mutableCopy];
57 | }
58 | return _pathPatterns;
59 | }
60 |
61 | - (NSMutableDictionary *)nameActionMapping
62 | {
63 | if(!_nameActionMapping)
64 | {
65 | _nameActionMapping = [@{} mutableCopy];
66 | }
67 | return _nameActionMapping;
68 | }
69 |
70 | - (NSMutableDictionary *)nameControllerMapping
71 | {
72 | if(!_nameControllerMapping)
73 | {
74 | _nameControllerMapping = [@{} mutableCopy];
75 | }
76 | return _nameControllerMapping;
77 | }
78 |
79 | - (NSMutableDictionary *)pathActionMapping
80 | {
81 | if(!_pathActionMapping)
82 | {
83 | _pathActionMapping = [@{} mutableCopy];
84 | }
85 | return _pathActionMapping;
86 | }
87 |
88 | - (NSMutableDictionary *)pathControllerMapping
89 | {
90 | if(!_pathControllerMapping)
91 | {
92 | _pathControllerMapping = [@{} mutableCopy];
93 | }
94 | return _pathControllerMapping;
95 | }
96 |
97 | - (void)addName:(NSString *)name
98 | path:(NSString *)path
99 | controller:(__kindof UIViewController *(^)(void))controller
100 | action:(void(^)(__kindof UIViewController *controller))action;
101 | {
102 | path = [self dn_parsePath:path];
103 |
104 | self.nameActionMapping[name] = action;
105 | self.nameControllerMapping[name] = controller;
106 |
107 | self.pathActionMapping[path] = action;
108 | self.pathControllerMapping[path] = controller;
109 |
110 | if([self dn_isDynamicPattern:path])
111 | {
112 | [self.pathPatterns insertObject:path atIndex:0];
113 | }
114 | else
115 | {
116 | [self.pathPatterns addObject:path];
117 | }
118 | }
119 |
120 | - (DNAction *)actionOfName:(NSString *)name
121 | {
122 | if(![self.nameControllerMapping objectForKey:name]) return nil;
123 | DNAction *action = [[DNAction alloc]init];
124 | action.action = self.nameActionMapping[name];
125 | action.controller = self.nameControllerMapping[name];
126 | action.behavior = DNActionAttachedBehavior;
127 | return action;
128 | }
129 |
130 | - (NSArray *)actionsOfPath:(NSString *)path
131 | {
132 | NSDictionary *queryItems = [self queryItemsInPath:&path];
133 | NSMutableArray *actions = [@[] mutableCopy];
134 |
135 | NSRange ar = [self dn_rangeOfActionPattern:path];
136 | NSMutableString *mp = [path mutableCopy];
137 |
138 | NSString *scheme;
139 | mp = [self dn_removeRangeOfSchemePattern:path scheme:&scheme];
140 |
141 | if((scheme && ![[scheme lowercaseString] isEqualToString:[self.scheme lowercaseString]]) || !mp) return nil;
142 |
143 | //normal scheme action
144 | if(ar.length < 3)
145 | {
146 | DNAction *pop = [self dn_popActionOfRange:ar];
147 |
148 | if(pop) [actions addObject:pop];
149 |
150 | if(ar.length > 0) [mp deleteCharactersInRange:ar];
151 | while(mp.length > 0)
152 | {
153 | NSString *pattern, *queryId;
154 | NSRange mpr = [self dn_rangeOfPattern:mp pattern:&pattern queryId:&queryId];
155 | if(mpr.location != NSNotFound)
156 | {
157 | DNAction *action = [[DNAction alloc]init];
158 | action.behavior = DNActionAttachedBehavior;
159 | action.queryItems = queryItems;
160 | action.queryId = queryId;
161 |
162 | action.controller = self.pathControllerMapping[pattern];
163 | action.action = self.pathActionMapping[pattern];
164 |
165 | [actions addObject:action];
166 |
167 | [mp deleteCharactersInRange:mpr];
168 | }
169 | else
170 | {
171 | mp = [@"" mutableCopy];
172 | }
173 | }
174 |
175 | return actions;
176 | }
177 | return nil;
178 | }
179 |
180 | - (NSString *)dn_parsePath:(NSString *)path
181 | {
182 | //remove the last '/' characters to make uniform path
183 | NSString *pattern = @"(/+)$";
184 | NSRange range = [path rangeOfString:pattern
185 | options:NSRegularExpressionSearch];
186 |
187 | if(range.location != NSNotFound) path = [path stringByReplacingCharactersInRange:range withString:@""];
188 |
189 |
190 | //the dynamic path should have prior right for matching
191 | NSRange dr = [path rangeOfString:DN_REGEX_DYNAMIC_PATH
192 | options:NSRegularExpressionSearch];
193 | if(dr.location != NSNotFound)
194 | {
195 | dr = [path rangeOfString:DN_REGEX_DYNAMIC_VALUE_PATH
196 | options:NSRegularExpressionSearch];
197 | path = [path stringByReplacingCharactersInRange:dr
198 | withString:DN_REGEX_DYNAMIC_VALUE_SUFFIX];
199 | }
200 |
201 | //return path regex should match from head
202 | path = [NSString stringWithFormat:@"^%@",path];
203 | return path;
204 | }
205 |
206 | - (BOOL)dn_isDynamicPattern:(NSString *)path
207 | {
208 | if([path hasSuffix:DN_REGEX_DYNAMIC_VALUE_SUFFIX])
209 | {
210 | return YES;
211 | }
212 | return NO;
213 | }
214 |
215 | - (DNAction *)dn_popActionOfRange:(NSRange)range
216 | {
217 | DNAction *action = [[DNAction alloc]init];
218 | if(range.length == 2) {action.behavior = DNActionPopBehavior; return action;}
219 | if(range.length == 0) {action.behavior = DNActionPopToRootBehavior; return action;}
220 | return nil;
221 | }
222 |
223 | //match scheme
224 | - (NSMutableString *)dn_removeRangeOfSchemePattern:(NSString *)path scheme:(NSString **)scheme
225 | {
226 | NSRange range = [path rangeOfString:DN_REGEX_SCHEME_PREFIX
227 | options:NSRegularExpressionSearch];
228 | NSMutableString *ms = [path mutableCopy];
229 |
230 | if(range.location != NSNotFound)
231 | {
232 | NSRange sr = [path rangeOfString:DN_REGEX_SCHEME
233 | options:NSRegularExpressionSearch];
234 | *scheme = [path substringWithRange:sr];
235 |
236 | [ms deleteCharactersInRange:NSMakeRange(sr.location, sr.length + 2)];
237 | return ms;
238 | }
239 |
240 | return ms;
241 | }
242 |
243 | //match ./ ../ or /
244 | - (NSRange )dn_rangeOfActionPattern:(NSString *)path
245 | {
246 | NSString *pattern = @"^\\.*";
247 | NSRange range = [path rangeOfString:pattern
248 | options:NSRegularExpressionSearch];
249 | return range;
250 | }
251 |
252 | //match pattern
253 | - (NSRange)dn_rangeOfPattern:(NSString *)path pattern:(NSString **)pattern queryId:(NSString **)queryId
254 | {
255 | NSRange range;
256 | for(NSString *p in self.pathPatterns)
257 | {
258 | range = [path rangeOfString:p
259 | options:NSRegularExpressionSearch];
260 |
261 | if(range.location != NSNotFound)
262 | {
263 | *pattern = p;
264 |
265 | if([self dn_isDynamicPattern:p])
266 | {
267 | NSString *dynamicPart = [path substringWithRange:range];
268 |
269 | NSRange dr = [path rangeOfString:DN_REGEX_DYNAMIC_VALUE_SUFFIX
270 | options:NSRegularExpressionSearch];
271 |
272 | if(dr.location != NSNotFound) *queryId = [dynamicPart substringWithRange:dr];
273 | return range;
274 | }
275 |
276 | return range;
277 | }
278 | }
279 | return range;
280 | }
281 |
282 | - (NSDictionary *)queryItemsInPath:(NSString **)path
283 | {
284 | NSMutableDictionary *queryItems = [@{} mutableCopy];
285 |
286 | NSRange paramsRange = [*path rangeOfString:DN_REGEX_PARAMS_SUFFIX
287 | options:NSRegularExpressionSearch];
288 |
289 |
290 |
291 | if(paramsRange.location == NSNotFound) return nil;
292 |
293 | NSMutableString *mParams = [[*path substringWithRange:paramsRange] mutableCopy];
294 |
295 | NSMutableString *mPath = [*path mutableCopy];
296 | [mPath deleteCharactersInRange:paramsRange];
297 | *path = mPath;
298 |
299 | while (mParams.length > 0) {
300 | NSRange r = [mParams rangeOfString:DN_REGEX_PARAMS_UNIT
301 | options:NSRegularExpressionSearch];
302 |
303 | if(r.location != NSNotFound)
304 | {
305 | NSString *matched = [mParams substringWithRange:r];
306 | NSArray *sliced = [matched componentsSeparatedByString:@"="];
307 | if(sliced.count == 2)
308 | {
309 | NSString *key = [self dn_trimDontCareCharacters:sliced[0]];
310 | NSString *value = [self dn_trimDontCareCharacters:sliced[1]];
311 | queryItems[key] = value;
312 | }
313 | [mParams deleteCharactersInRange:NSMakeRange(r.location - 1, r.length + 1)];
314 | }
315 | else
316 | {
317 | mParams = [@"" mutableCopy];
318 | }
319 | }
320 |
321 | if(queryItems.allKeys.count == 0) return nil;
322 |
323 | return [queryItems copy];
324 | }
325 |
326 | - (NSString *)dn_trimDontCareCharacters:(NSString *)c
327 | {
328 | c = [c stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
329 | c = [c stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"=&?"]];
330 | return c;;
331 | }
332 |
333 |
334 | @end
335 |
--------------------------------------------------------------------------------
/DarwinNativeRouter.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1A0F1E921CA940C0003013D4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A0F1E911CA940C0003013D4 /* main.m */; };
11 | 1A0F1E951CA940C0003013D4 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A0F1E941CA940C0003013D4 /* AppDelegate.m */; };
12 | 1A0F1E981CA940C0003013D4 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A0F1E971CA940C0003013D4 /* ViewController.m */; };
13 | 1A0F1E9B1CA940C0003013D4 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1A0F1E991CA940C0003013D4 /* Main.storyboard */; };
14 | 1A0F1E9D1CA940C0003013D4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1A0F1E9C1CA940C0003013D4 /* Assets.xcassets */; };
15 | 1A0F1EA01CA940C0003013D4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1A0F1E9E1CA940C0003013D4 /* LaunchScreen.storyboard */; };
16 | 1A0F1EAB1CA940C0003013D4 /* DarwinNativeRouterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A0F1EAA1CA940C0003013D4 /* DarwinNativeRouterTests.m */; };
17 | 1A0F1EB61CA940C0003013D4 /* DarwinNativeRouterUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A0F1EB51CA940C0003013D4 /* DarwinNativeRouterUITests.m */; };
18 | 1A2D979C1CAE50AB00F033B2 /* DNRouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A2D97971CAE50AB00F033B2 /* DNRouter.m */; };
19 | 1A2D979D1CAE50AB00F033B2 /* DNRouterCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A2D97991CAE50AB00F033B2 /* DNRouterCenter.m */; };
20 | 1A2D979E1CAE50AC00F033B2 /* UIViewController+DNRouterExtra.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A2D979B1CAE50AB00F033B2 /* UIViewController+DNRouterExtra.m */; };
21 | /* End PBXBuildFile section */
22 |
23 | /* Begin PBXContainerItemProxy section */
24 | 1A0F1EA71CA940C0003013D4 /* PBXContainerItemProxy */ = {
25 | isa = PBXContainerItemProxy;
26 | containerPortal = 1A0F1E851CA940C0003013D4 /* Project object */;
27 | proxyType = 1;
28 | remoteGlobalIDString = 1A0F1E8C1CA940C0003013D4;
29 | remoteInfo = DarwinNativeRouter;
30 | };
31 | 1A0F1EB21CA940C0003013D4 /* PBXContainerItemProxy */ = {
32 | isa = PBXContainerItemProxy;
33 | containerPortal = 1A0F1E851CA940C0003013D4 /* Project object */;
34 | proxyType = 1;
35 | remoteGlobalIDString = 1A0F1E8C1CA940C0003013D4;
36 | remoteInfo = DarwinNativeRouter;
37 | };
38 | /* End PBXContainerItemProxy section */
39 |
40 | /* Begin PBXFileReference section */
41 | 1A0F1E8D1CA940C0003013D4 /* DarwinNativeRouter.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DarwinNativeRouter.app; sourceTree = BUILT_PRODUCTS_DIR; };
42 | 1A0F1E911CA940C0003013D4 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
43 | 1A0F1E931CA940C0003013D4 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
44 | 1A0F1E941CA940C0003013D4 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
45 | 1A0F1E961CA940C0003013D4 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
46 | 1A0F1E971CA940C0003013D4 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
47 | 1A0F1E9A1CA940C0003013D4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
48 | 1A0F1E9C1CA940C0003013D4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
49 | 1A0F1E9F1CA940C0003013D4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
50 | 1A0F1EA11CA940C0003013D4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
51 | 1A0F1EA61CA940C0003013D4 /* DarwinNativeRouterTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DarwinNativeRouterTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
52 | 1A0F1EAA1CA940C0003013D4 /* DarwinNativeRouterTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DarwinNativeRouterTests.m; sourceTree = ""; };
53 | 1A0F1EAC1CA940C0003013D4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
54 | 1A0F1EB11CA940C0003013D4 /* DarwinNativeRouterUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DarwinNativeRouterUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
55 | 1A0F1EB51CA940C0003013D4 /* DarwinNativeRouterUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DarwinNativeRouterUITests.m; sourceTree = ""; };
56 | 1A0F1EB71CA940C0003013D4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
57 | 1A2D97951CAE50AB00F033B2 /* DarwinNativeRouter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DarwinNativeRouter.h; sourceTree = ""; };
58 | 1A2D97961CAE50AB00F033B2 /* DNRouter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNRouter.h; sourceTree = ""; };
59 | 1A2D97971CAE50AB00F033B2 /* DNRouter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DNRouter.m; sourceTree = ""; };
60 | 1A2D97981CAE50AB00F033B2 /* DNRouterCenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DNRouterCenter.h; sourceTree = ""; };
61 | 1A2D97991CAE50AB00F033B2 /* DNRouterCenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DNRouterCenter.m; sourceTree = ""; };
62 | 1A2D979A1CAE50AB00F033B2 /* UIViewController+DNRouterExtra.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+DNRouterExtra.h"; sourceTree = ""; };
63 | 1A2D979B1CAE50AB00F033B2 /* UIViewController+DNRouterExtra.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+DNRouterExtra.m"; sourceTree = ""; };
64 | /* End PBXFileReference section */
65 |
66 | /* Begin PBXFrameworksBuildPhase section */
67 | 1A0F1E8A1CA940C0003013D4 /* Frameworks */ = {
68 | isa = PBXFrameworksBuildPhase;
69 | buildActionMask = 2147483647;
70 | files = (
71 | );
72 | runOnlyForDeploymentPostprocessing = 0;
73 | };
74 | 1A0F1EA31CA940C0003013D4 /* Frameworks */ = {
75 | isa = PBXFrameworksBuildPhase;
76 | buildActionMask = 2147483647;
77 | files = (
78 | );
79 | runOnlyForDeploymentPostprocessing = 0;
80 | };
81 | 1A0F1EAE1CA940C0003013D4 /* Frameworks */ = {
82 | isa = PBXFrameworksBuildPhase;
83 | buildActionMask = 2147483647;
84 | files = (
85 | );
86 | runOnlyForDeploymentPostprocessing = 0;
87 | };
88 | /* End PBXFrameworksBuildPhase section */
89 |
90 | /* Begin PBXGroup section */
91 | 1A0F1E841CA940C0003013D4 = {
92 | isa = PBXGroup;
93 | children = (
94 | 1A0F1E8F1CA940C0003013D4 /* DarwinNativeRouter */,
95 | 1A0F1EA91CA940C0003013D4 /* DarwinNativeRouterTests */,
96 | 1A0F1EB41CA940C0003013D4 /* DarwinNativeRouterUITests */,
97 | 1A0F1E8E1CA940C0003013D4 /* Products */,
98 | );
99 | sourceTree = "";
100 | };
101 | 1A0F1E8E1CA940C0003013D4 /* Products */ = {
102 | isa = PBXGroup;
103 | children = (
104 | 1A0F1E8D1CA940C0003013D4 /* DarwinNativeRouter.app */,
105 | 1A0F1EA61CA940C0003013D4 /* DarwinNativeRouterTests.xctest */,
106 | 1A0F1EB11CA940C0003013D4 /* DarwinNativeRouterUITests.xctest */,
107 | );
108 | name = Products;
109 | sourceTree = "";
110 | };
111 | 1A0F1E8F1CA940C0003013D4 /* DarwinNativeRouter */ = {
112 | isa = PBXGroup;
113 | children = (
114 | 1A2D97941CAE50AB00F033B2 /* DarwinNativeRouter */,
115 | 1A0F1E931CA940C0003013D4 /* AppDelegate.h */,
116 | 1A0F1E941CA940C0003013D4 /* AppDelegate.m */,
117 | 1A0F1E961CA940C0003013D4 /* ViewController.h */,
118 | 1A0F1E971CA940C0003013D4 /* ViewController.m */,
119 | 1A0F1E991CA940C0003013D4 /* Main.storyboard */,
120 | 1A0F1E9C1CA940C0003013D4 /* Assets.xcassets */,
121 | 1A0F1E9E1CA940C0003013D4 /* LaunchScreen.storyboard */,
122 | 1A0F1EA11CA940C0003013D4 /* Info.plist */,
123 | 1A0F1E901CA940C0003013D4 /* Supporting Files */,
124 | );
125 | path = DarwinNativeRouter;
126 | sourceTree = "";
127 | };
128 | 1A0F1E901CA940C0003013D4 /* Supporting Files */ = {
129 | isa = PBXGroup;
130 | children = (
131 | 1A0F1E911CA940C0003013D4 /* main.m */,
132 | );
133 | name = "Supporting Files";
134 | sourceTree = "";
135 | };
136 | 1A0F1EA91CA940C0003013D4 /* DarwinNativeRouterTests */ = {
137 | isa = PBXGroup;
138 | children = (
139 | 1A0F1EAA1CA940C0003013D4 /* DarwinNativeRouterTests.m */,
140 | 1A0F1EAC1CA940C0003013D4 /* Info.plist */,
141 | );
142 | path = DarwinNativeRouterTests;
143 | sourceTree = "";
144 | };
145 | 1A0F1EB41CA940C0003013D4 /* DarwinNativeRouterUITests */ = {
146 | isa = PBXGroup;
147 | children = (
148 | 1A0F1EB51CA940C0003013D4 /* DarwinNativeRouterUITests.m */,
149 | 1A0F1EB71CA940C0003013D4 /* Info.plist */,
150 | );
151 | path = DarwinNativeRouterUITests;
152 | sourceTree = "";
153 | };
154 | 1A2D97941CAE50AB00F033B2 /* DarwinNativeRouter */ = {
155 | isa = PBXGroup;
156 | children = (
157 | 1A2D97951CAE50AB00F033B2 /* DarwinNativeRouter.h */,
158 | 1A2D97961CAE50AB00F033B2 /* DNRouter.h */,
159 | 1A2D97971CAE50AB00F033B2 /* DNRouter.m */,
160 | 1A2D97981CAE50AB00F033B2 /* DNRouterCenter.h */,
161 | 1A2D97991CAE50AB00F033B2 /* DNRouterCenter.m */,
162 | 1A2D979A1CAE50AB00F033B2 /* UIViewController+DNRouterExtra.h */,
163 | 1A2D979B1CAE50AB00F033B2 /* UIViewController+DNRouterExtra.m */,
164 | );
165 | path = DarwinNativeRouter;
166 | sourceTree = "";
167 | };
168 | /* End PBXGroup section */
169 |
170 | /* Begin PBXNativeTarget section */
171 | 1A0F1E8C1CA940C0003013D4 /* DarwinNativeRouter */ = {
172 | isa = PBXNativeTarget;
173 | buildConfigurationList = 1A0F1EBA1CA940C0003013D4 /* Build configuration list for PBXNativeTarget "DarwinNativeRouter" */;
174 | buildPhases = (
175 | 1A0F1E891CA940C0003013D4 /* Sources */,
176 | 1A0F1E8A1CA940C0003013D4 /* Frameworks */,
177 | 1A0F1E8B1CA940C0003013D4 /* Resources */,
178 | );
179 | buildRules = (
180 | );
181 | dependencies = (
182 | );
183 | name = DarwinNativeRouter;
184 | productName = DarwinNativeRouter;
185 | productReference = 1A0F1E8D1CA940C0003013D4 /* DarwinNativeRouter.app */;
186 | productType = "com.apple.product-type.application";
187 | };
188 | 1A0F1EA51CA940C0003013D4 /* DarwinNativeRouterTests */ = {
189 | isa = PBXNativeTarget;
190 | buildConfigurationList = 1A0F1EBD1CA940C0003013D4 /* Build configuration list for PBXNativeTarget "DarwinNativeRouterTests" */;
191 | buildPhases = (
192 | 1A0F1EA21CA940C0003013D4 /* Sources */,
193 | 1A0F1EA31CA940C0003013D4 /* Frameworks */,
194 | 1A0F1EA41CA940C0003013D4 /* Resources */,
195 | );
196 | buildRules = (
197 | );
198 | dependencies = (
199 | 1A0F1EA81CA940C0003013D4 /* PBXTargetDependency */,
200 | );
201 | name = DarwinNativeRouterTests;
202 | productName = DarwinNativeRouterTests;
203 | productReference = 1A0F1EA61CA940C0003013D4 /* DarwinNativeRouterTests.xctest */;
204 | productType = "com.apple.product-type.bundle.unit-test";
205 | };
206 | 1A0F1EB01CA940C0003013D4 /* DarwinNativeRouterUITests */ = {
207 | isa = PBXNativeTarget;
208 | buildConfigurationList = 1A0F1EC01CA940C0003013D4 /* Build configuration list for PBXNativeTarget "DarwinNativeRouterUITests" */;
209 | buildPhases = (
210 | 1A0F1EAD1CA940C0003013D4 /* Sources */,
211 | 1A0F1EAE1CA940C0003013D4 /* Frameworks */,
212 | 1A0F1EAF1CA940C0003013D4 /* Resources */,
213 | );
214 | buildRules = (
215 | );
216 | dependencies = (
217 | 1A0F1EB31CA940C0003013D4 /* PBXTargetDependency */,
218 | );
219 | name = DarwinNativeRouterUITests;
220 | productName = DarwinNativeRouterUITests;
221 | productReference = 1A0F1EB11CA940C0003013D4 /* DarwinNativeRouterUITests.xctest */;
222 | productType = "com.apple.product-type.bundle.ui-testing";
223 | };
224 | /* End PBXNativeTarget section */
225 |
226 | /* Begin PBXProject section */
227 | 1A0F1E851CA940C0003013D4 /* Project object */ = {
228 | isa = PBXProject;
229 | attributes = {
230 | LastUpgradeCheck = 0710;
231 | ORGANIZATIONNAME = oenius;
232 | TargetAttributes = {
233 | 1A0F1E8C1CA940C0003013D4 = {
234 | CreatedOnToolsVersion = 7.1;
235 | };
236 | 1A0F1EA51CA940C0003013D4 = {
237 | CreatedOnToolsVersion = 7.1;
238 | TestTargetID = 1A0F1E8C1CA940C0003013D4;
239 | };
240 | 1A0F1EB01CA940C0003013D4 = {
241 | CreatedOnToolsVersion = 7.1;
242 | TestTargetID = 1A0F1E8C1CA940C0003013D4;
243 | };
244 | };
245 | };
246 | buildConfigurationList = 1A0F1E881CA940C0003013D4 /* Build configuration list for PBXProject "DarwinNativeRouter" */;
247 | compatibilityVersion = "Xcode 3.2";
248 | developmentRegion = English;
249 | hasScannedForEncodings = 0;
250 | knownRegions = (
251 | en,
252 | Base,
253 | );
254 | mainGroup = 1A0F1E841CA940C0003013D4;
255 | productRefGroup = 1A0F1E8E1CA940C0003013D4 /* Products */;
256 | projectDirPath = "";
257 | projectRoot = "";
258 | targets = (
259 | 1A0F1E8C1CA940C0003013D4 /* DarwinNativeRouter */,
260 | 1A0F1EA51CA940C0003013D4 /* DarwinNativeRouterTests */,
261 | 1A0F1EB01CA940C0003013D4 /* DarwinNativeRouterUITests */,
262 | );
263 | };
264 | /* End PBXProject section */
265 |
266 | /* Begin PBXResourcesBuildPhase section */
267 | 1A0F1E8B1CA940C0003013D4 /* Resources */ = {
268 | isa = PBXResourcesBuildPhase;
269 | buildActionMask = 2147483647;
270 | files = (
271 | 1A0F1EA01CA940C0003013D4 /* LaunchScreen.storyboard in Resources */,
272 | 1A0F1E9D1CA940C0003013D4 /* Assets.xcassets in Resources */,
273 | 1A0F1E9B1CA940C0003013D4 /* Main.storyboard in Resources */,
274 | );
275 | runOnlyForDeploymentPostprocessing = 0;
276 | };
277 | 1A0F1EA41CA940C0003013D4 /* Resources */ = {
278 | isa = PBXResourcesBuildPhase;
279 | buildActionMask = 2147483647;
280 | files = (
281 | );
282 | runOnlyForDeploymentPostprocessing = 0;
283 | };
284 | 1A0F1EAF1CA940C0003013D4 /* Resources */ = {
285 | isa = PBXResourcesBuildPhase;
286 | buildActionMask = 2147483647;
287 | files = (
288 | );
289 | runOnlyForDeploymentPostprocessing = 0;
290 | };
291 | /* End PBXResourcesBuildPhase section */
292 |
293 | /* Begin PBXSourcesBuildPhase section */
294 | 1A0F1E891CA940C0003013D4 /* Sources */ = {
295 | isa = PBXSourcesBuildPhase;
296 | buildActionMask = 2147483647;
297 | files = (
298 | 1A2D979C1CAE50AB00F033B2 /* DNRouter.m in Sources */,
299 | 1A0F1E981CA940C0003013D4 /* ViewController.m in Sources */,
300 | 1A2D979E1CAE50AC00F033B2 /* UIViewController+DNRouterExtra.m in Sources */,
301 | 1A0F1E951CA940C0003013D4 /* AppDelegate.m in Sources */,
302 | 1A2D979D1CAE50AB00F033B2 /* DNRouterCenter.m in Sources */,
303 | 1A0F1E921CA940C0003013D4 /* main.m in Sources */,
304 | );
305 | runOnlyForDeploymentPostprocessing = 0;
306 | };
307 | 1A0F1EA21CA940C0003013D4 /* Sources */ = {
308 | isa = PBXSourcesBuildPhase;
309 | buildActionMask = 2147483647;
310 | files = (
311 | 1A0F1EAB1CA940C0003013D4 /* DarwinNativeRouterTests.m in Sources */,
312 | );
313 | runOnlyForDeploymentPostprocessing = 0;
314 | };
315 | 1A0F1EAD1CA940C0003013D4 /* Sources */ = {
316 | isa = PBXSourcesBuildPhase;
317 | buildActionMask = 2147483647;
318 | files = (
319 | 1A0F1EB61CA940C0003013D4 /* DarwinNativeRouterUITests.m in Sources */,
320 | );
321 | runOnlyForDeploymentPostprocessing = 0;
322 | };
323 | /* End PBXSourcesBuildPhase section */
324 |
325 | /* Begin PBXTargetDependency section */
326 | 1A0F1EA81CA940C0003013D4 /* PBXTargetDependency */ = {
327 | isa = PBXTargetDependency;
328 | target = 1A0F1E8C1CA940C0003013D4 /* DarwinNativeRouter */;
329 | targetProxy = 1A0F1EA71CA940C0003013D4 /* PBXContainerItemProxy */;
330 | };
331 | 1A0F1EB31CA940C0003013D4 /* PBXTargetDependency */ = {
332 | isa = PBXTargetDependency;
333 | target = 1A0F1E8C1CA940C0003013D4 /* DarwinNativeRouter */;
334 | targetProxy = 1A0F1EB21CA940C0003013D4 /* PBXContainerItemProxy */;
335 | };
336 | /* End PBXTargetDependency section */
337 |
338 | /* Begin PBXVariantGroup section */
339 | 1A0F1E991CA940C0003013D4 /* Main.storyboard */ = {
340 | isa = PBXVariantGroup;
341 | children = (
342 | 1A0F1E9A1CA940C0003013D4 /* Base */,
343 | );
344 | name = Main.storyboard;
345 | sourceTree = "";
346 | };
347 | 1A0F1E9E1CA940C0003013D4 /* LaunchScreen.storyboard */ = {
348 | isa = PBXVariantGroup;
349 | children = (
350 | 1A0F1E9F1CA940C0003013D4 /* Base */,
351 | );
352 | name = LaunchScreen.storyboard;
353 | sourceTree = "";
354 | };
355 | /* End PBXVariantGroup section */
356 |
357 | /* Begin XCBuildConfiguration section */
358 | 1A0F1EB81CA940C0003013D4 /* Debug */ = {
359 | isa = XCBuildConfiguration;
360 | buildSettings = {
361 | ALWAYS_SEARCH_USER_PATHS = NO;
362 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
363 | CLANG_CXX_LIBRARY = "libc++";
364 | CLANG_ENABLE_MODULES = YES;
365 | CLANG_ENABLE_OBJC_ARC = YES;
366 | CLANG_WARN_BOOL_CONVERSION = YES;
367 | CLANG_WARN_CONSTANT_CONVERSION = YES;
368 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
369 | CLANG_WARN_EMPTY_BODY = YES;
370 | CLANG_WARN_ENUM_CONVERSION = YES;
371 | CLANG_WARN_INT_CONVERSION = YES;
372 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
373 | CLANG_WARN_UNREACHABLE_CODE = YES;
374 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
375 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
376 | COPY_PHASE_STRIP = NO;
377 | DEBUG_INFORMATION_FORMAT = dwarf;
378 | ENABLE_STRICT_OBJC_MSGSEND = YES;
379 | ENABLE_TESTABILITY = YES;
380 | GCC_C_LANGUAGE_STANDARD = gnu99;
381 | GCC_DYNAMIC_NO_PIC = NO;
382 | GCC_NO_COMMON_BLOCKS = YES;
383 | GCC_OPTIMIZATION_LEVEL = 0;
384 | GCC_PREPROCESSOR_DEFINITIONS = (
385 | "DEBUG=1",
386 | "$(inherited)",
387 | );
388 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
389 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
390 | GCC_WARN_UNDECLARED_SELECTOR = YES;
391 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
392 | GCC_WARN_UNUSED_FUNCTION = YES;
393 | GCC_WARN_UNUSED_VARIABLE = YES;
394 | IPHONEOS_DEPLOYMENT_TARGET = 9.1;
395 | MTL_ENABLE_DEBUG_INFO = YES;
396 | ONLY_ACTIVE_ARCH = YES;
397 | SDKROOT = iphoneos;
398 | };
399 | name = Debug;
400 | };
401 | 1A0F1EB91CA940C0003013D4 /* Release */ = {
402 | isa = XCBuildConfiguration;
403 | buildSettings = {
404 | ALWAYS_SEARCH_USER_PATHS = NO;
405 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
406 | CLANG_CXX_LIBRARY = "libc++";
407 | CLANG_ENABLE_MODULES = YES;
408 | CLANG_ENABLE_OBJC_ARC = YES;
409 | CLANG_WARN_BOOL_CONVERSION = YES;
410 | CLANG_WARN_CONSTANT_CONVERSION = YES;
411 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
412 | CLANG_WARN_EMPTY_BODY = YES;
413 | CLANG_WARN_ENUM_CONVERSION = YES;
414 | CLANG_WARN_INT_CONVERSION = YES;
415 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
416 | CLANG_WARN_UNREACHABLE_CODE = YES;
417 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
418 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
419 | COPY_PHASE_STRIP = NO;
420 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
421 | ENABLE_NS_ASSERTIONS = NO;
422 | ENABLE_STRICT_OBJC_MSGSEND = YES;
423 | GCC_C_LANGUAGE_STANDARD = gnu99;
424 | GCC_NO_COMMON_BLOCKS = YES;
425 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
426 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
427 | GCC_WARN_UNDECLARED_SELECTOR = YES;
428 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
429 | GCC_WARN_UNUSED_FUNCTION = YES;
430 | GCC_WARN_UNUSED_VARIABLE = YES;
431 | IPHONEOS_DEPLOYMENT_TARGET = 9.1;
432 | MTL_ENABLE_DEBUG_INFO = NO;
433 | SDKROOT = iphoneos;
434 | VALIDATE_PRODUCT = YES;
435 | };
436 | name = Release;
437 | };
438 | 1A0F1EBB1CA940C0003013D4 /* Debug */ = {
439 | isa = XCBuildConfiguration;
440 | buildSettings = {
441 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
442 | INFOPLIST_FILE = DarwinNativeRouter/Info.plist;
443 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
444 | PRODUCT_BUNDLE_IDENTIFIER = com.oenius.jou.DarwinNativeRouter;
445 | PRODUCT_NAME = "$(TARGET_NAME)";
446 | };
447 | name = Debug;
448 | };
449 | 1A0F1EBC1CA940C0003013D4 /* Release */ = {
450 | isa = XCBuildConfiguration;
451 | buildSettings = {
452 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
453 | INFOPLIST_FILE = DarwinNativeRouter/Info.plist;
454 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
455 | PRODUCT_BUNDLE_IDENTIFIER = com.oenius.jou.DarwinNativeRouter;
456 | PRODUCT_NAME = "$(TARGET_NAME)";
457 | };
458 | name = Release;
459 | };
460 | 1A0F1EBE1CA940C0003013D4 /* Debug */ = {
461 | isa = XCBuildConfiguration;
462 | buildSettings = {
463 | BUNDLE_LOADER = "$(TEST_HOST)";
464 | INFOPLIST_FILE = DarwinNativeRouterTests/Info.plist;
465 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
466 | PRODUCT_BUNDLE_IDENTIFIER = com.oenius.jou.DarwinNativeRouterTests;
467 | PRODUCT_NAME = "$(TARGET_NAME)";
468 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DarwinNativeRouter.app/DarwinNativeRouter";
469 | };
470 | name = Debug;
471 | };
472 | 1A0F1EBF1CA940C0003013D4 /* Release */ = {
473 | isa = XCBuildConfiguration;
474 | buildSettings = {
475 | BUNDLE_LOADER = "$(TEST_HOST)";
476 | INFOPLIST_FILE = DarwinNativeRouterTests/Info.plist;
477 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
478 | PRODUCT_BUNDLE_IDENTIFIER = com.oenius.jou.DarwinNativeRouterTests;
479 | PRODUCT_NAME = "$(TARGET_NAME)";
480 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DarwinNativeRouter.app/DarwinNativeRouter";
481 | };
482 | name = Release;
483 | };
484 | 1A0F1EC11CA940C0003013D4 /* Debug */ = {
485 | isa = XCBuildConfiguration;
486 | buildSettings = {
487 | INFOPLIST_FILE = DarwinNativeRouterUITests/Info.plist;
488 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
489 | PRODUCT_BUNDLE_IDENTIFIER = com.oenius.jou.DarwinNativeRouterUITests;
490 | PRODUCT_NAME = "$(TARGET_NAME)";
491 | TEST_TARGET_NAME = DarwinNativeRouter;
492 | USES_XCTRUNNER = YES;
493 | };
494 | name = Debug;
495 | };
496 | 1A0F1EC21CA940C0003013D4 /* Release */ = {
497 | isa = XCBuildConfiguration;
498 | buildSettings = {
499 | INFOPLIST_FILE = DarwinNativeRouterUITests/Info.plist;
500 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
501 | PRODUCT_BUNDLE_IDENTIFIER = com.oenius.jou.DarwinNativeRouterUITests;
502 | PRODUCT_NAME = "$(TARGET_NAME)";
503 | TEST_TARGET_NAME = DarwinNativeRouter;
504 | USES_XCTRUNNER = YES;
505 | };
506 | name = Release;
507 | };
508 | /* End XCBuildConfiguration section */
509 |
510 | /* Begin XCConfigurationList section */
511 | 1A0F1E881CA940C0003013D4 /* Build configuration list for PBXProject "DarwinNativeRouter" */ = {
512 | isa = XCConfigurationList;
513 | buildConfigurations = (
514 | 1A0F1EB81CA940C0003013D4 /* Debug */,
515 | 1A0F1EB91CA940C0003013D4 /* Release */,
516 | );
517 | defaultConfigurationIsVisible = 0;
518 | defaultConfigurationName = Release;
519 | };
520 | 1A0F1EBA1CA940C0003013D4 /* Build configuration list for PBXNativeTarget "DarwinNativeRouter" */ = {
521 | isa = XCConfigurationList;
522 | buildConfigurations = (
523 | 1A0F1EBB1CA940C0003013D4 /* Debug */,
524 | 1A0F1EBC1CA940C0003013D4 /* Release */,
525 | );
526 | defaultConfigurationIsVisible = 0;
527 | defaultConfigurationName = Release;
528 | };
529 | 1A0F1EBD1CA940C0003013D4 /* Build configuration list for PBXNativeTarget "DarwinNativeRouterTests" */ = {
530 | isa = XCConfigurationList;
531 | buildConfigurations = (
532 | 1A0F1EBE1CA940C0003013D4 /* Debug */,
533 | 1A0F1EBF1CA940C0003013D4 /* Release */,
534 | );
535 | defaultConfigurationIsVisible = 0;
536 | defaultConfigurationName = Release;
537 | };
538 | 1A0F1EC01CA940C0003013D4 /* Build configuration list for PBXNativeTarget "DarwinNativeRouterUITests" */ = {
539 | isa = XCConfigurationList;
540 | buildConfigurations = (
541 | 1A0F1EC11CA940C0003013D4 /* Debug */,
542 | 1A0F1EC21CA940C0003013D4 /* Release */,
543 | );
544 | defaultConfigurationIsVisible = 0;
545 | defaultConfigurationName = Release;
546 | };
547 | /* End XCConfigurationList section */
548 | };
549 | rootObject = 1A0F1E851CA940C0003013D4 /* Project object */;
550 | }
551 |
--------------------------------------------------------------------------------