├── 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 | --------------------------------------------------------------------------------