├── .gitignore
├── Example
├── LJRouter.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── LJRouter-Example.xcscheme
│ │ └── LJRouterExportModule.xcscheme
├── LJRouter.xcworkspace
│ └── contents.xcworkspacedata
├── LJRouter
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── Images.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── LJAppDelegate.h
│ ├── LJAppDelegate.m
│ ├── LJHomeComponent
│ │ ├── LJHomeTabBarController.m
│ │ └── LJHomeViewController.m
│ ├── LJLoginComponent
│ │ └── LJLoginViewController.m
│ ├── LJPersonalComponent
│ │ ├── LJMyProfileViewController.m
│ │ └── LJSettingViewController.m
│ ├── LJRouter-Info.plist
│ ├── LJRouter-Prefix.pch
│ ├── LJWebviewComponent
│ │ └── LJWebViewController.m
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ └── main.m
├── Podfile
├── Podfile.lock
├── Pods
│ ├── Headers
│ │ ├── Private
│ │ │ └── LJRouter
│ │ │ │ ├── LJInvocationCenter.h
│ │ │ │ ├── LJRouter.h
│ │ │ │ ├── LJRouterConvertManager.h
│ │ │ │ ├── LJRouterPrivate.h
│ │ │ │ ├── LJUrlRouter.h
│ │ │ │ ├── UIViewController+LJNavigation.h
│ │ │ │ └── metamacros.h
│ │ └── Public
│ │ │ └── LJRouter
│ │ │ ├── LJInvocationCenter.h
│ │ │ ├── LJRouter.h
│ │ │ ├── LJRouterConvertManager.h
│ │ │ ├── LJRouterPrivate.h
│ │ │ ├── LJUrlRouter.h
│ │ │ ├── UIViewController+LJNavigation.h
│ │ │ └── metamacros.h
│ ├── Local Podspecs
│ │ └── LJRouter.podspec.json
│ ├── Manifest.lock
│ ├── Pods.xcodeproj
│ │ └── project.pbxproj
│ └── Target Support Files
│ │ ├── LJRouter
│ │ ├── LJRouter-dummy.m
│ │ ├── LJRouter-prefix.pch
│ │ └── LJRouter.xcconfig
│ │ └── Pods-LJRouter_Example
│ │ ├── Pods-LJRouter_Example-acknowledgements.markdown
│ │ ├── Pods-LJRouter_Example-acknowledgements.plist
│ │ ├── Pods-LJRouter_Example-dummy.m
│ │ ├── Pods-LJRouter_Example-frameworks.sh
│ │ ├── Pods-LJRouter_Example-resources.sh
│ │ ├── Pods-LJRouter_Example.debug.xcconfig
│ │ └── Pods-LJRouter_Example.release.xcconfig
└── outputHeaders
│ ├── LJHomeComponentHeader.h
│ ├── LJLoginComponentHeader.h
│ ├── LJPersonalComponentHeader.h
│ ├── LJWebviewComponentHeader.h
│ ├── action.json
│ └── page.json
├── LICENSE
├── LJRouter.podspec
├── LJRouter
├── Core
│ ├── LJInvocationCenter.h
│ ├── LJInvocationCenter.m
│ ├── LJRouter.h
│ ├── LJRouter.m
│ ├── LJRouterConvertManager.h
│ ├── LJRouterConvertManager.m
│ ├── LJRouterPrivate.h
│ ├── LJUrlRouter.h
│ ├── LJUrlRouter.m
│ └── metamacros.h
├── ExportDocument
│ └── LJRouterExportDevDocument.m
├── ExportTool
│ ├── LJRouterExportModule.h
│ └── LJRouterExportModule.m
└── Navigation
│ ├── UIViewController+LJNavigation.h
│ └── UIViewController+LJNavigation.m
├── README.md
├── _Pods.xcodeproj
└── build
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xccheckout
23 | *.xcscmblueprint
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 | *.ipa
28 | *.dSYM.zip
29 | *.dSYM
30 |
31 | # CocoaPods
32 | #
33 | # We recommend against adding the Pods directory to your .gitignore. However
34 | # you should judge for yourself, the pros and cons are mentioned at:
35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
36 | #
37 | # Pods/
38 |
39 | # Carthage
40 | #
41 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
42 | # Carthage/Checkouts
43 |
44 | Carthage/Build
45 |
46 | # fastlane
47 | #
48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
49 | # screenshots whenever they are needed.
50 | # For more information about the recommended setup visit:
51 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
52 |
53 | fastlane/report.xml
54 | fastlane/Preview.html
55 | fastlane/screenshots
56 | fastlane/test_output
57 |
58 | # Code Injection
59 | #
60 | # After new code Injection tools there's a generated folder /iOSInjectionProject
61 | # https://github.com/johnno1962/injectionforxcode
62 |
63 | iOSInjectionProject/
64 |
--------------------------------------------------------------------------------
/Example/LJRouter.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/LJRouter.xcodeproj/xcshareddata/xcschemes/LJRouter-Example.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
34 |
40 |
41 |
42 |
43 |
44 |
50 |
51 |
52 |
53 |
54 |
55 |
66 |
68 |
74 |
75 |
76 |
77 |
78 |
79 |
85 |
87 |
93 |
94 |
95 |
96 |
98 |
99 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/Example/LJRouter.xcodeproj/xcshareddata/xcschemes/LJRouterExportModule.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
56 |
58 |
64 |
65 |
66 |
67 |
70 |
71 |
74 |
75 |
76 |
77 |
81 |
82 |
86 |
87 |
91 |
92 |
93 |
94 |
95 |
96 |
102 |
104 |
110 |
111 |
112 |
113 |
115 |
116 |
119 |
120 |
121 |
--------------------------------------------------------------------------------
/Example/LJRouter.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Example/LJRouter/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 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Example/LJRouter/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Example/LJRouter/LJAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // LJAppDelegate.h
3 | // LJRouter
4 | //
5 | // Created by fover0 on 06/23/2017.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | @import UIKit;
10 |
11 | @interface LJAppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Example/LJRouter/LJAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // LJAppDelegate.m
3 | // LJRouter
4 | //
5 | // Created by fover0 on 06/23/2017.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | #import "LJAppDelegate.h"
10 | #import "LJRouter.h"
11 | #import "LJUrlRouter.h"
12 | #import "UIViewController+LJNavigation.h"
13 |
14 | @implementation LJAppDelegate
15 |
16 | LJRouterUsePageObj(webview, (NSString*)url);
17 | - (void)globalConfig
18 | {
19 | [LJRouter sharedInstance].checkPolicy = LJRouterCheckPolicyAssert;
20 | // [LJRouter sharedInstance].checkPolicyModules = @[@"LJPersonalComponent"];
21 | [LJRouter sharedInstance].createWebviewBlock = ^UIViewController *(NSString *url) {
22 | return get_webview_controller_with_url(url);
23 | };
24 |
25 | [[LJRouter sharedInstance].convertManager
26 | addConvertJsonValueBlock:^id(LJRouterConvertManager *manager,
27 | void *value,
28 | LJInvocationCenterItemParam *valueParam) {
29 | if ([valueParam.objcClass isKindOfClass:[NSDictionary class]]
30 | || [valueParam.objcClass isKindOfClass:[NSArray class]])
31 | {
32 | void** p = (void**)value;
33 | id dict = (__bridge id)(*p);
34 | NSData *data =
35 | [NSJSONSerialization dataWithJSONObject:dict
36 | options:0
37 | error:nil];
38 | return [[NSString alloc] initWithData:data
39 | encoding:NSUTF8StringEncoding];
40 | }
41 | return nil;
42 | }];
43 |
44 | [[LJRouter sharedInstance].convertManager addCovertInvokeValueBlock:
45 | ^LJRouterConvertInvokeValue *(LJRouterConvertManager *manager,
46 | id value,
47 | LJInvocationCenterItemParam *targetParam) {
48 | if ([value isKindOfClass:[NSString class]])
49 | {
50 | if (targetParam.objcClass == [NSDictionary class]
51 | || targetParam.objcClass == [NSArray class])
52 | {
53 | NSData *stringData = [value dataUsingEncoding:NSUTF8StringEncoding];
54 | id jsonObj = [NSJSONSerialization JSONObjectWithData:stringData options:0 error:nil];
55 | if ([jsonObj isKindOfClass:targetParam.objcClass])
56 | {
57 | return [LJRouterConvertInvokeValue valueWithRetainObj:jsonObj];
58 | }
59 | }
60 | }
61 | return nil;
62 | }];
63 | }
64 |
65 | LJRouterUsePageObj(homeTabbar);
66 |
67 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
68 | {
69 | [self globalConfig];
70 |
71 | UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
72 | UINavigationController *vc = [[UINavigationController alloc] initWithRootViewController:get_homeTabbar_controller()];
73 | window.rootViewController = vc;
74 | self.window = window ;
75 | [window makeKeyAndVisible];
76 |
77 | return YES;
78 | }
79 |
80 | - (BOOL)application:(UIApplication *)app
81 | openURL:(NSURL *)url
82 | options:(NSDictionary *)options
83 | {
84 | return
85 | [[LJRouter sharedInstance] routerUrlString:url.absoluteString
86 | sender:self
87 | pageBlock:^(__kindof UIViewController *viewController) {
88 | [UIViewController LJNavigationOpenViewController:viewController];
89 | }
90 | callbackBlock:nil
91 | canNotRouterBlock:nil];
92 | }
93 |
94 | - (void)applicationWillResignActive:(UIApplication *)application
95 | {
96 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
97 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
98 | }
99 |
100 | - (void)applicationDidEnterBackground:(UIApplication *)application
101 | {
102 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
103 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
104 | }
105 |
106 | - (void)applicationWillEnterForeground:(UIApplication *)application
107 | {
108 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
109 | }
110 |
111 | - (void)applicationDidBecomeActive:(UIApplication *)application
112 | {
113 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
114 | }
115 |
116 | - (void)applicationWillTerminate:(UIApplication *)application
117 | {
118 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
119 | }
120 |
121 | @end
122 |
--------------------------------------------------------------------------------
/Example/LJRouter/LJHomeComponent/LJHomeTabBarController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LJHomeTabBarController.m
3 | // invocation
4 | //
5 | // Created by fover0 on 2017/6/20.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | #import "LJRouter.h"
10 | #import "UIViewController+LJNavigation.h"
11 | @interface LJHomeTabBarController : UITabBarController
12 |
13 | @end
14 |
15 | @implementation LJHomeTabBarController
16 |
17 | LJRouterUsePageObj(Home, (NSString*)titlex);
18 | LJRouterUsePageObj(setting);
19 |
20 | @end
21 |
22 | @interface LJHomeTabBarController (something)
23 |
24 | @end
25 |
26 | @implementation LJHomeTabBarController(something)
27 |
28 | LJRouterInit(@"首页tabbar",homeTabbar)
29 | {
30 | self = [self init];
31 | if (self)
32 | {
33 | NSArray *viewcontrollers = @[
34 | get_Home_controller_with_titlex(@"我就是个title"),
35 | get_setting_controller(),
36 | ];
37 |
38 | self.viewControllers = viewcontrollers;
39 | }
40 | return self;
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/Example/LJRouter/LJHomeComponent/LJHomeViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LJHomeViewController.m
3 | // invocation
4 | //
5 | // Created by fover0 on 2017/6/8.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | #import "LJRouter.h"
10 | #import "LJUrlRouter.h"
11 |
12 | @interface LJHomeViewController : UIViewController
13 |
14 | @end
15 |
16 | @implementation LJHomeViewController
17 |
18 | LJRouterInit(@"2017年新版首页",
19 | Home,
20 | (NSString*)titlex)
21 | {
22 | self = [super init];
23 | if (self)
24 | {
25 | self.title = titlex;
26 | }
27 | return self;
28 | }
29 |
30 | - (void)viewDidLoad
31 | {
32 | [super viewDidLoad];
33 | self.view.backgroundColor = [UIColor whiteColor];
34 | {
35 | UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100,100,200,100)];
36 | [btn setTitle:@"push webview with url" forState:0];
37 | btn.backgroundColor = [UIColor redColor];
38 | [btn addTarget:self action:@selector(click) forControlEvents:UIControlEventTouchUpInside];
39 | [self.view addSubview:btn];
40 | }
41 | {
42 | UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100,300,200,100)];
43 | [btn setTitle:@"push webview urlstring" forState:0];
44 | btn.backgroundColor = [UIColor redColor];
45 | [btn addTarget:self action:@selector(click2) forControlEvents:UIControlEventTouchUpInside];
46 | [self.view addSubview:btn];
47 | }
48 | }
49 |
50 | - (void)click
51 | {
52 | [self LJOpenUrlString:@"https://www.lianjia.com"];
53 | }
54 |
55 | LJRouterUsePage(webview,(NSString*)htmlString);
56 | - (void)click2
57 | {
58 | NSArray *urls = @[@"lianjia://somejscmd?str=heihei&callback=callbackFunction",
59 | @"lianjia://setWebViewTitle?title=你好",
60 | @"lianjia://setWebViewTitle2?title=哈喽",
61 | @"lianjia://myProfile?userId=666",
62 | @"lianjia://myProfile?user={\"userid\":\"123\"}",];
63 | NSMutableString *string = [[NSMutableString alloc] initWithString:@""];
64 |
65 | for (NSString *url in urls)
66 | {
67 | [string appendFormat:@"%@
",url,url];
68 | }
69 |
70 | open_webview_controller_with_htmlString(self, string);
71 | }
72 |
73 | @end
74 |
75 | @interface LJHomeViewController (something)
76 | @end
77 |
78 | @implementation LJHomeViewController (something)
79 |
80 | LJRouterInit(@"泛型测试", objectTypeTest,(NSDictionary*)aaa)
81 | {
82 | return [self init];
83 | }
84 |
85 | @end
86 |
--------------------------------------------------------------------------------
/Example/LJRouter/LJLoginComponent/LJLoginViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LJLoginViewController.m
3 | // invocation
4 | //
5 | // Created by fover0 on 2017/6/20.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | #import "LJRouter.h"
10 | #import "UIViewController+LJNavigation.h"
11 |
12 | @interface LJLoginViewController : UIViewController
13 | @property (nonatomic, copy) void(^finishBlock)(BOOL);
14 | @end
15 |
16 | @implementation LJLoginViewController
17 |
18 | + (void)initialize
19 | {
20 | NSLog(@"%s",__func__);
21 | }
22 |
23 | LJRouterInit(@"登录页面", login)
24 | {
25 | self = [super init];
26 | if (self)
27 | {
28 | self.ljNavigationType = LJNavigationTypePresentWithNavigation;
29 | self.title = @"登录";
30 | }
31 | return self;
32 | }
33 |
34 | LJRouterRegistAction(@"判断登录状态,弹出登录页面", loginIfNeed, void, (UIViewController*)curVC, (void(^)(BOOL))finishBlock)
35 | {
36 | if ([[[NSUserDefaults standardUserDefaults] valueForKey:@"islogin"] isEqualToString:@"1"])
37 | {
38 | if (finishBlock)
39 | {
40 | finishBlock(YES);
41 | }
42 | }
43 | else
44 | {
45 | LJLoginViewController *vc = [self get_login_controller];
46 | vc.finishBlock = finishBlock;
47 | [curVC LJNavigationOpenViewController:vc];
48 | }
49 | }
50 |
51 | LJRouterRegistAction(@"是否登录状态", isLogin, BOOL)
52 | {
53 | return [[[NSUserDefaults standardUserDefaults] valueForKey:@"islogin"] isEqualToString:@"1"];
54 | }
55 |
56 | LJRouterRegistAction(@"退出登录", logout, void)
57 | {
58 | [[NSUserDefaults standardUserDefaults] setValue:nil forKey:@"islogin"];
59 | }
60 |
61 |
62 | - (void)viewDidLoad
63 | {
64 | [super viewDidLoad];
65 | self.view.backgroundColor = [UIColor whiteColor];
66 | {
67 | UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100,100,200,100)];
68 | [btn setTitle:@"login" forState:0];
69 | btn.backgroundColor = [UIColor redColor];
70 | [btn addTarget:self action:@selector(click) forControlEvents:UIControlEventTouchUpInside];
71 | [self.view addSubview:btn];
72 | }
73 |
74 | {
75 | UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100,300,200,100)];
76 | [btn setTitle:@"cancel" forState:0];
77 | btn.backgroundColor = [UIColor redColor];
78 | [btn addTarget:self action:@selector(click2) forControlEvents:UIControlEventTouchUpInside];
79 | [self.view addSubview:btn];
80 | }
81 | }
82 |
83 | - (void)click
84 | {
85 | [[NSUserDefaults standardUserDefaults] setValue:@"1" forKey:@"islogin"];
86 | [self closeSelf];
87 | if (self.finishBlock)
88 | {
89 | self.finishBlock(YES);
90 | }
91 | }
92 |
93 | - (void)click2
94 | {
95 | [self closeSelf];
96 | if (self.finishBlock)
97 | {
98 | self.finishBlock(NO);
99 | }
100 |
101 | }
102 |
103 | @end
104 |
--------------------------------------------------------------------------------
/Example/LJRouter/LJPersonalComponent/LJMyProfileViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LJMyProfileViewController.m
3 | // invocation
4 | //
5 | // Created by fover0 on 2017/6/20.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | #import "LJRouter.h"
10 | #import "UIViewController+LJNavigation.h"
11 |
12 | @interface LJMyProfileViewController : UIViewController
13 | @end
14 |
15 | @implementation LJMyProfileViewController
16 |
17 | LJRouterInit(@"我的个人页",myProfile,(unsigned long)userId)
18 | {
19 | self = [super init];
20 | if (self)
21 | {
22 | NSString *title = [NSString stringWithFormat:@"我的页面 id=%lu",userId];
23 | self.title = title;
24 | }
25 | return self;
26 | }
27 |
28 | LJRouterInit(@"个人页", myProfile,(NSDictionary*)user)
29 | {
30 | self = [super init];
31 | if (self)
32 | {
33 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[[user class] description]
34 | message:user.description
35 | delegate:nil
36 | cancelButtonTitle:@"ok"
37 | otherButtonTitles:nil, nil];
38 | [alert show];
39 | }
40 | return self;
41 | }
42 |
43 | - (void)viewDidLoad
44 | {
45 | [super viewDidLoad];
46 | self.view.backgroundColor = [UIColor whiteColor];
47 | }
48 |
49 | - (void)viewDidAppear:(BOOL)animated
50 | {
51 | [super viewDidAppear:animated];
52 | UITabBarController *tabbarController = self.navigationController.viewControllers.firstObject;
53 | [tabbarController.viewControllers enumerateObjectsUsingBlock:^(__kindof UIViewController * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
54 | if ([obj.ljRouterKey isEqualToString:@"setting"])
55 | {
56 | tabbarController.selectedIndex = idx;
57 | *stop = YES;
58 | return ;
59 | }
60 | }];
61 | }
62 |
63 | LJRouterUseAction(loginIfNeed, void, (UIViewController*)curVC, (void(^)(BOOL))finishBlock);
64 | - (void)LJNavigationOpenedByViewController:(__kindof UIViewController *)viewController
65 | {
66 | // 这里是登录
67 | action_loginIfNeed_with_curVC_finishBlock(viewController,^(BOOL succeed) {
68 | if (succeed)
69 | {
70 | if ([self.tabBarController.selectedViewController.ljRouterKey isEqualToString:@"setting"])
71 | {
72 | [super LJNavigationOpenedByViewController:viewController];
73 | }
74 | else
75 | {
76 | [viewController.navigationController setViewControllers:@[viewController.navigationController.viewControllers.firstObject,self] animated:YES];
77 | }
78 | }
79 | else
80 | {
81 | // login fail do nothing
82 | }
83 | });
84 | }
85 |
86 | @end
87 |
--------------------------------------------------------------------------------
/Example/LJRouter/LJPersonalComponent/LJSettingViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LJSettingViewController.m
3 | // invocation
4 | //
5 | // Created by fover0 on 2017/6/20.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | #import "LJRouter.h"
10 |
11 | @interface LJSettingViewController : UIViewController
12 | @end
13 |
14 | @implementation LJSettingViewController
15 |
16 | LJRouterInit(@"设置页面", setting)
17 | {
18 | self = [super init];
19 | if (self)
20 | {
21 | self.title = @"设置";
22 | }
23 | return self;
24 | }
25 |
26 | - (void)viewDidLoad
27 | {
28 | [super viewDidLoad];
29 | self.view.backgroundColor = [UIColor whiteColor];
30 | {
31 | UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100,100,200,100)];
32 | [btn setTitle:@"个人信息" forState:0];
33 | btn.backgroundColor = [UIColor redColor];
34 | [btn addTarget:self action:@selector(click) forControlEvents:UIControlEventTouchUpInside];
35 | [self.view addSubview:btn];
36 | }
37 |
38 | {
39 | UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100,300,200,100)];
40 | [btn setTitle:@"退出登录" forState:0];
41 | btn.backgroundColor = [UIColor redColor];
42 | [btn addTarget:self action:@selector(click2) forControlEvents:UIControlEventTouchUpInside];
43 | [self.view addSubview:btn];
44 | }
45 | }
46 |
47 | LJRouterUsePage(myProfile, (unsigned long)userId);
48 | - (void)click
49 | {
50 | open_myProfile_controller_with_userId(self, 1000);
51 | }
52 |
53 | LJRouterUseAction(logout, void);
54 | - (void)click2
55 | {
56 | action_logout();
57 | UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"已经退出" message:nil preferredStyle:UIAlertControllerStyleAlert];
58 | [alert addAction:[UIAlertAction actionWithTitle:@"ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
59 |
60 | }]];
61 | [self presentViewController:alert animated:YES completion:nil];
62 | }
63 |
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/Example/LJRouter/LJRouter-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleURLTypes
24 |
25 |
26 | CFBundleTypeRole
27 | Editor
28 | CFBundleURLName
29 | lianjia
30 | CFBundleURLSchemes
31 |
32 | lje
33 |
34 |
35 |
36 | CFBundleVersion
37 | 1.0
38 | LSRequiresIPhoneOS
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Example/LJRouter/LJRouter-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #import
8 |
9 | #ifdef __OBJC__
10 | @import UIKit;
11 | @import Foundation;
12 | #import
13 | #endif
14 |
--------------------------------------------------------------------------------
/Example/LJRouter/LJWebviewComponent/LJWebViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LJWebViewController.m
3 | // invocation
4 | //
5 | // Created by fover0 on 2017/6/18.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | #import "LJRouter.h"
10 | #import "LJUrlRouter.h"
11 |
12 | @interface LJWebViewController : UIViewController
13 | @property (nonatomic, retain) UIWebView *webview;
14 | @property (nonatomic, copy) NSString *htmlString;
15 | @property (nonatomic, copy) NSString *url;
16 | @end
17 |
18 | @implementation LJWebViewController
19 |
20 | LJRouterInit(@"webview",
21 | webview,
22 | (NSString*)url)
23 | {
24 | self = [super initWithNibName:nil bundle:nil];
25 | if (self)
26 | {
27 | self.url = url;
28 | }
29 | return self;
30 | }
31 |
32 | LJRouterInit(@"webview",
33 | webview,
34 | (NSString*)htmlString)
35 | {
36 | self = [super initWithNibName:nil bundle:nil];
37 | if (self)
38 | {
39 | self.htmlString = htmlString;
40 | }
41 | return self;
42 | }
43 |
44 |
45 | LJRouterRegistAction(@"接收js命令// 接收一个字符串 添加_haha结尾",
46 | somejscmd,
47 | void,(NSString*)str,
48 | (LJRouterCallbackBlock)callback)
49 | {
50 | callback(@"1",NO);
51 | callback(@"2",NO);
52 | callback([str stringByAppendingString:@"_haha"],YES);
53 | }
54 |
55 | LJRouterRegistAction(@"设置UIWebView标题", setWebViewTitle, void,(UIWebView*)sender,(NSString*)title)
56 | {
57 | if (![sender isKindOfClass:[UIView class]])
58 | {
59 | return;
60 | }
61 | UIResponder *responder = sender ;
62 | while (responder) {
63 | responder = [responder nextResponder];
64 | if ([responder isKindOfClass:[UIViewController class]])
65 | {
66 | UIViewController *vc = (id)responder;
67 | vc.title = title;
68 | }
69 | }
70 | }
71 |
72 | LJRouterRegistAction(@"设置UIWebView标题", setWebViewTitle2, void,(LJRouterSenderContext*)sender,(NSString*)title)
73 | {
74 | sender.contextViewController.title = title;
75 | }
76 |
77 | - (void)viewDidLoad {
78 | [super viewDidLoad];
79 | UIWebView *webview = [[UIWebView alloc] initWithFrame:self.view.bounds];
80 | self.webview = webview;
81 | [self.view addSubview:webview];
82 | webview.delegate = self;
83 |
84 |
85 | if (self.url.length)
86 | {
87 | [webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.url]]];
88 | }
89 | else if (self.htmlString.length)
90 | {
91 | [webview loadHTMLString:self.htmlString baseURL:nil];
92 | }
93 | }
94 |
95 | - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
96 | {
97 | if ([request.URL.scheme hasPrefix:@"lianjia"])
98 | {
99 | return !
100 | [[LJRouter sharedInstance] routerUrlString:request.URL.absoluteString
101 | sender:webView
102 | pageBlock:^(__kindof UIViewController *viewController) {
103 | [[LJRouter sharedInstance] openViewController:viewController withSender:self];
104 | }
105 | callbackBlock:^(NSString *key, NSString *value, NSString *data, BOOL complete) {
106 | if (value.length && data.length)
107 | {
108 | NSString *cmd = [[NSString alloc] initWithFormat:@"%@('%@');",value,data];
109 | [self.webview stringByEvaluatingJavaScriptFromString:cmd];
110 | }
111 | }
112 | canNotRouterBlock:nil];
113 | }
114 | return YES;
115 | }
116 |
117 | @end
118 |
--------------------------------------------------------------------------------
/Example/LJRouter/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Example/LJRouter/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // LJRouter
4 | //
5 | // Created by fover0 on 06/23/2017.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | @import UIKit;
10 | #import "LJAppDelegate.h"
11 |
12 | int main(int argc, char * argv[])
13 | {
14 | @autoreleasepool {
15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([LJAppDelegate class]));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Example/Podfile:
--------------------------------------------------------------------------------
1 | source 'http://git.lianjia.com/mobile_ios/Lianjia_component_Podspec.git'
2 |
3 | target 'LJRouter_Example' do
4 | pod 'LJRouter', :path => '../'
5 | end
6 |
7 |
--------------------------------------------------------------------------------
/Example/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - LJRouter (0.7.0):
3 | - LJRouter/Core (= 0.7.0)
4 | - LJRouter/Navigation (= 0.7.0)
5 | - LJRouter/Core (0.7.0)
6 | - LJRouter/Navigation (0.7.0)
7 |
8 | DEPENDENCIES:
9 | - LJRouter (from `../`)
10 |
11 | EXTERNAL SOURCES:
12 | LJRouter:
13 | :path: ../
14 |
15 | SPEC CHECKSUMS:
16 | LJRouter: d053c8cc9b7f54bf18a2a3dca9ddf61ace7ec00c
17 |
18 | PODFILE CHECKSUM: 31444511aaf50633ab2e4b8ab8d4887ee12ec0e6
19 |
20 | COCOAPODS: 1.4.0.rc.1
21 |
--------------------------------------------------------------------------------
/Example/Pods/Headers/Private/LJRouter/LJInvocationCenter.h:
--------------------------------------------------------------------------------
1 | ../../../../../LJRouter/Core/LJInvocationCenter.h
--------------------------------------------------------------------------------
/Example/Pods/Headers/Private/LJRouter/LJRouter.h:
--------------------------------------------------------------------------------
1 | ../../../../../LJRouter/Core/LJRouter.h
--------------------------------------------------------------------------------
/Example/Pods/Headers/Private/LJRouter/LJRouterConvertManager.h:
--------------------------------------------------------------------------------
1 | ../../../../../LJRouter/Core/LJRouterConvertManager.h
--------------------------------------------------------------------------------
/Example/Pods/Headers/Private/LJRouter/LJRouterPrivate.h:
--------------------------------------------------------------------------------
1 | ../../../../../LJRouter/Core/LJRouterPrivate.h
--------------------------------------------------------------------------------
/Example/Pods/Headers/Private/LJRouter/LJUrlRouter.h:
--------------------------------------------------------------------------------
1 | ../../../../../LJRouter/Core/LJUrlRouter.h
--------------------------------------------------------------------------------
/Example/Pods/Headers/Private/LJRouter/UIViewController+LJNavigation.h:
--------------------------------------------------------------------------------
1 | ../../../../../LJRouter/Navigation/UIViewController+LJNavigation.h
--------------------------------------------------------------------------------
/Example/Pods/Headers/Private/LJRouter/metamacros.h:
--------------------------------------------------------------------------------
1 | ../../../../../LJRouter/Core/metamacros.h
--------------------------------------------------------------------------------
/Example/Pods/Headers/Public/LJRouter/LJInvocationCenter.h:
--------------------------------------------------------------------------------
1 | ../../../../../LJRouter/Core/LJInvocationCenter.h
--------------------------------------------------------------------------------
/Example/Pods/Headers/Public/LJRouter/LJRouter.h:
--------------------------------------------------------------------------------
1 | ../../../../../LJRouter/Core/LJRouter.h
--------------------------------------------------------------------------------
/Example/Pods/Headers/Public/LJRouter/LJRouterConvertManager.h:
--------------------------------------------------------------------------------
1 | ../../../../../LJRouter/Core/LJRouterConvertManager.h
--------------------------------------------------------------------------------
/Example/Pods/Headers/Public/LJRouter/LJRouterPrivate.h:
--------------------------------------------------------------------------------
1 | ../../../../../LJRouter/Core/LJRouterPrivate.h
--------------------------------------------------------------------------------
/Example/Pods/Headers/Public/LJRouter/LJUrlRouter.h:
--------------------------------------------------------------------------------
1 | ../../../../../LJRouter/Core/LJUrlRouter.h
--------------------------------------------------------------------------------
/Example/Pods/Headers/Public/LJRouter/UIViewController+LJNavigation.h:
--------------------------------------------------------------------------------
1 | ../../../../../LJRouter/Navigation/UIViewController+LJNavigation.h
--------------------------------------------------------------------------------
/Example/Pods/Headers/Public/LJRouter/metamacros.h:
--------------------------------------------------------------------------------
1 | ../../../../../LJRouter/Core/metamacros.h
--------------------------------------------------------------------------------
/Example/Pods/Local Podspecs/LJRouter.podspec.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "LJRouter",
3 | "version": "0.7.0",
4 | "summary": "链家iOS路由方案",
5 | "description": "LJRouter是链家独立开发完成的ios客户端路由跳转模块,该模块在接入,安全性,易用性都有比较好的表现,一行代码即可支持h5交互,push跳转,url scheme跳转等功能并实时生成文档.",
6 | "homepage": "https://github.com/LianjiaTech/LJRouter",
7 | "license": {
8 | "type": "MIT",
9 | "file": "LICENSE"
10 | },
11 | "authors": {
12 | "chenxi": "fover0@126.com"
13 | },
14 | "source": {
15 | "git": "https://github.com/LianjiaTech/LJRouter.git",
16 | "tag": "0.7.0"
17 | },
18 | "preserve_paths": [
19 | "LJRouter/ExportTool",
20 | "LJRouter/ExportDocument",
21 | "build"
22 | ],
23 | "platforms": {
24 | "ios": "8.0"
25 | },
26 | "ios": {
27 | "frameworks": "UIKit"
28 | },
29 | "default_subspecs": [
30 | "Core",
31 | "Navigation"
32 | ],
33 | "subspecs": [
34 | {
35 | "name": "Core",
36 | "source_files": "LJRouter/Core/**/*"
37 | },
38 | {
39 | "name": "Navigation",
40 | "source_files": "LJRouter/Navigation/**/*"
41 | }
42 | ]
43 | }
44 |
--------------------------------------------------------------------------------
/Example/Pods/Manifest.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - LJRouter (0.7.0):
3 | - LJRouter/Core (= 0.7.0)
4 | - LJRouter/Navigation (= 0.7.0)
5 | - LJRouter/Core (0.7.0)
6 | - LJRouter/Navigation (0.7.0)
7 |
8 | DEPENDENCIES:
9 | - LJRouter (from `../`)
10 |
11 | EXTERNAL SOURCES:
12 | LJRouter:
13 | :path: ../
14 |
15 | SPEC CHECKSUMS:
16 | LJRouter: d053c8cc9b7f54bf18a2a3dca9ddf61ace7ec00c
17 |
18 | PODFILE CHECKSUM: 31444511aaf50633ab2e4b8ab8d4887ee12ec0e6
19 |
20 | COCOAPODS: 1.4.0.rc.1
21 |
--------------------------------------------------------------------------------
/Example/Pods/Pods.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 0083AD54101A8F2BC28D49D9EB763D0B /* LJUrlRouter.h in Headers */ = {isa = PBXBuildFile; fileRef = 92BD04E298C527A993D751A7C4E1A4DB /* LJUrlRouter.h */; settings = {ATTRIBUTES = (Project, ); }; };
11 | 1035915AE1C08B61DC1E9EF0E95B1FF8 /* Pods-LJRouter_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C424084C8EE1138C637D11025DC793B1 /* Pods-LJRouter_Example-dummy.m */; };
12 | 23570B18BE6B1B9FFC424F8810669353 /* LJRouterPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 5055C7A26BFE8346EB06FC9AE2B30A84 /* LJRouterPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; };
13 | 48BF8C7DE9DBE5A20CD338741D476CBA /* LJRouter.h in Headers */ = {isa = PBXBuildFile; fileRef = 5253CBE066A29BEC2D8ED51A7688C504 /* LJRouter.h */; settings = {ATTRIBUTES = (Project, ); }; };
14 | 665FB8709EB20255F270B3BB34D88B82 /* metamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 0DC2F486D6A8BCD8F34CE19A2DC87D43 /* metamacros.h */; settings = {ATTRIBUTES = (Project, ); }; };
15 | 6731DAC759CA8658E123FB13446E536F /* LJRouter-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = CB871749505B51AFD97BFC6EB727B6C4 /* LJRouter-dummy.m */; };
16 | 68518674328950BAF3BEC991415DEAD9 /* LJUrlRouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 869699ECA91E76BDFFD3653A042ECC7B /* LJUrlRouter.m */; };
17 | 6D0B910509F817D70D790C8B3805AF36 /* LJRouter.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C26D5A481D864D7D66AE596AF516E34 /* LJRouter.m */; };
18 | 729D3AFB73234094614EE8A20C565055 /* LJRouterConvertManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 3022823B2E59F6312D3679DEC79D2812 /* LJRouterConvertManager.h */; settings = {ATTRIBUTES = (Project, ); }; };
19 | 7A40A411BDDC481FE089F9032DA92BCB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D88AAE1F92055A60CC2FC970D7D34634 /* Foundation.framework */; };
20 | 81440BE60992DE7F04E32F4D384C221C /* UIViewController+LJNavigation.h in Headers */ = {isa = PBXBuildFile; fileRef = 9384EA1EC3F9F880AA95D9CAAB2448D8 /* UIViewController+LJNavigation.h */; settings = {ATTRIBUTES = (Project, ); }; };
21 | 834C0829F0FE1DB8C77F46B8D06ABC05 /* LJRouterConvertManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CE3F4E9A34CAE905CF1E57C8C16D397F /* LJRouterConvertManager.m */; };
22 | 8B0146414ECA1EA9F23A87BCEBDAA59D /* UIViewController+LJNavigation.m in Sources */ = {isa = PBXBuildFile; fileRef = 2F713603D0BC5DAC1825045E3C343A24 /* UIViewController+LJNavigation.m */; };
23 | C15B89E3AF780159CA74790D99D19DAE /* LJInvocationCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = CDE6E56A0E64223D07310757724CC6AC /* LJInvocationCenter.m */; };
24 | C97CB8CFFDBAEAA0E9367845FAD5094B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D88AAE1F92055A60CC2FC970D7D34634 /* Foundation.framework */; };
25 | E0BE10049AAC2890F685169DBA6ED71F /* LJInvocationCenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 18D79562941659CE24837C803B462E99 /* LJInvocationCenter.h */; settings = {ATTRIBUTES = (Project, ); }; };
26 | F9546ED236764DFF2BDFF8BF59EC01A2 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B63C6A64CF66340668996F78DA6BB482 /* UIKit.framework */; };
27 | /* End PBXBuildFile section */
28 |
29 | /* Begin PBXContainerItemProxy section */
30 | B7187F05F56362033182C1726625EA75 /* PBXContainerItemProxy */ = {
31 | isa = PBXContainerItemProxy;
32 | containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
33 | proxyType = 1;
34 | remoteGlobalIDString = AEE6E99EB3157BC0AFF77C9FE07B7392;
35 | remoteInfo = LJRouter;
36 | };
37 | /* End PBXContainerItemProxy section */
38 |
39 | /* Begin PBXFileReference section */
40 | 0DC2F486D6A8BCD8F34CE19A2DC87D43 /* metamacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = metamacros.h; path = LJRouter/Core/metamacros.h; sourceTree = ""; };
41 | 0FB445BF0199E908BD39EB33182BF612 /* libPods-LJRouter_Example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = "libPods-LJRouter_Example.a"; path = "libPods-LJRouter_Example.a"; sourceTree = BUILT_PRODUCTS_DIR; };
42 | 18D79562941659CE24837C803B462E99 /* LJInvocationCenter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = LJInvocationCenter.h; path = LJRouter/Core/LJInvocationCenter.h; sourceTree = ""; };
43 | 193344E2033F65E4E73190FB2BF8DCBF /* libLJRouter.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; name = libLJRouter.a; path = libLJRouter.a; sourceTree = BUILT_PRODUCTS_DIR; };
44 | 2114385887C3BC99E5382E89DB279F5F /* LJRouter.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; path = LJRouter.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
45 | 2F713603D0BC5DAC1825045E3C343A24 /* UIViewController+LJNavigation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIViewController+LJNavigation.m"; path = "LJRouter/Navigation/UIViewController+LJNavigation.m"; sourceTree = ""; };
46 | 3022823B2E59F6312D3679DEC79D2812 /* LJRouterConvertManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = LJRouterConvertManager.h; path = LJRouter/Core/LJRouterConvertManager.h; sourceTree = ""; };
47 | 33A0E83796DA88F4DC8F1B87B3E90A7F /* Pods-LJRouter_Example-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-LJRouter_Example-frameworks.sh"; sourceTree = ""; };
48 | 3C08F10EA3A8140D98270A2A0C60A9A3 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; };
49 | 5055C7A26BFE8346EB06FC9AE2B30A84 /* LJRouterPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = LJRouterPrivate.h; path = LJRouter/Core/LJRouterPrivate.h; sourceTree = ""; };
50 | 5253CBE066A29BEC2D8ED51A7688C504 /* LJRouter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = LJRouter.h; path = LJRouter/Core/LJRouter.h; sourceTree = ""; };
51 | 5C26D5A481D864D7D66AE596AF516E34 /* LJRouter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = LJRouter.m; path = LJRouter/Core/LJRouter.m; sourceTree = ""; };
52 | 725B0B9E990130908A56251D75A483BA /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; };
53 | 84BBA6949276A6302B39B74608EC7FEC /* LJRouter-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "LJRouter-prefix.pch"; sourceTree = ""; };
54 | 869699ECA91E76BDFFD3653A042ECC7B /* LJUrlRouter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = LJUrlRouter.m; path = LJRouter/Core/LJUrlRouter.m; sourceTree = ""; };
55 | 8AEC40840BA9158D5D389CA324D2121C /* Pods-LJRouter_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-LJRouter_Example.debug.xcconfig"; sourceTree = ""; };
56 | 92BD04E298C527A993D751A7C4E1A4DB /* LJUrlRouter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = LJUrlRouter.h; path = LJRouter/Core/LJUrlRouter.h; sourceTree = ""; };
57 | 9384EA1EC3F9F880AA95D9CAAB2448D8 /* UIViewController+LJNavigation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIViewController+LJNavigation.h"; path = "LJRouter/Navigation/UIViewController+LJNavigation.h"; sourceTree = ""; };
58 | 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
59 | 979AAAC514FB32C539F5C84B7155C1CC /* Pods-LJRouter_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-LJRouter_Example.release.xcconfig"; sourceTree = ""; };
60 | 9B149CCA91703BAB29C101853F2D873A /* Pods-LJRouter_Example-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-LJRouter_Example-resources.sh"; sourceTree = ""; };
61 | AAACCE311E62A263051AB128115292BE /* LJRouter.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = LJRouter.xcconfig; sourceTree = ""; };
62 | B63C6A64CF66340668996F78DA6BB482 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
63 | BC58743EFF4E5237B7926C81B6AE3BC4 /* Pods-LJRouter_Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-LJRouter_Example-acknowledgements.plist"; sourceTree = ""; };
64 | C424084C8EE1138C637D11025DC793B1 /* Pods-LJRouter_Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-LJRouter_Example-dummy.m"; sourceTree = ""; };
65 | CB871749505B51AFD97BFC6EB727B6C4 /* LJRouter-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "LJRouter-dummy.m"; sourceTree = ""; };
66 | CDE6E56A0E64223D07310757724CC6AC /* LJInvocationCenter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = LJInvocationCenter.m; path = LJRouter/Core/LJInvocationCenter.m; sourceTree = ""; };
67 | CE3F4E9A34CAE905CF1E57C8C16D397F /* LJRouterConvertManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = LJRouterConvertManager.m; path = LJRouter/Core/LJRouterConvertManager.m; sourceTree = ""; };
68 | D88AAE1F92055A60CC2FC970D7D34634 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
69 | F11DDBA8BE62EBF7D9BD808D482E89AF /* Pods-LJRouter_Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-LJRouter_Example-acknowledgements.markdown"; sourceTree = ""; };
70 | /* End PBXFileReference section */
71 |
72 | /* Begin PBXFrameworksBuildPhase section */
73 | 13A9F228798A263CBD90052D42D1A294 /* Frameworks */ = {
74 | isa = PBXFrameworksBuildPhase;
75 | buildActionMask = 2147483647;
76 | files = (
77 | 7A40A411BDDC481FE089F9032DA92BCB /* Foundation.framework in Frameworks */,
78 | F9546ED236764DFF2BDFF8BF59EC01A2 /* UIKit.framework in Frameworks */,
79 | );
80 | runOnlyForDeploymentPostprocessing = 0;
81 | };
82 | 6E8B39E1293010056503927B3CBAEA3E /* Frameworks */ = {
83 | isa = PBXFrameworksBuildPhase;
84 | buildActionMask = 2147483647;
85 | files = (
86 | C97CB8CFFDBAEAA0E9367845FAD5094B /* Foundation.framework in Frameworks */,
87 | );
88 | runOnlyForDeploymentPostprocessing = 0;
89 | };
90 | /* End PBXFrameworksBuildPhase section */
91 |
92 | /* Begin PBXGroup section */
93 | 0486F50E18EADC01A0D32B4277F7EAB1 /* Development Pods */ = {
94 | isa = PBXGroup;
95 | children = (
96 | 40256EE7B50C4BA7F8A675BCAEA15F8A /* LJRouter */,
97 | );
98 | name = "Development Pods";
99 | sourceTree = "";
100 | };
101 | 1CDDE9DADB57E938ED5F4CA0C9DBD311 /* Core */ = {
102 | isa = PBXGroup;
103 | children = (
104 | 18D79562941659CE24837C803B462E99 /* LJInvocationCenter.h */,
105 | CDE6E56A0E64223D07310757724CC6AC /* LJInvocationCenter.m */,
106 | 5253CBE066A29BEC2D8ED51A7688C504 /* LJRouter.h */,
107 | 5C26D5A481D864D7D66AE596AF516E34 /* LJRouter.m */,
108 | 3022823B2E59F6312D3679DEC79D2812 /* LJRouterConvertManager.h */,
109 | CE3F4E9A34CAE905CF1E57C8C16D397F /* LJRouterConvertManager.m */,
110 | 5055C7A26BFE8346EB06FC9AE2B30A84 /* LJRouterPrivate.h */,
111 | 92BD04E298C527A993D751A7C4E1A4DB /* LJUrlRouter.h */,
112 | 869699ECA91E76BDFFD3653A042ECC7B /* LJUrlRouter.m */,
113 | 0DC2F486D6A8BCD8F34CE19A2DC87D43 /* metamacros.h */,
114 | );
115 | name = Core;
116 | sourceTree = "";
117 | };
118 | 40256EE7B50C4BA7F8A675BCAEA15F8A /* LJRouter */ = {
119 | isa = PBXGroup;
120 | children = (
121 | 1CDDE9DADB57E938ED5F4CA0C9DBD311 /* Core */,
122 | ED4030E341AA953B088F68AD03BE2E28 /* Navigation */,
123 | 4DC29A2E985102ABF89929CB799C46BA /* Pod */,
124 | 5ADEED61D1E238C3A714D2C1D8538473 /* Support Files */,
125 | );
126 | name = LJRouter;
127 | path = ../..;
128 | sourceTree = "";
129 | };
130 | 433CD3331B6C3787F473C941B61FC68F /* Frameworks */ = {
131 | isa = PBXGroup;
132 | children = (
133 | 438B396F6B4147076630CAEFE34282C1 /* iOS */,
134 | );
135 | name = Frameworks;
136 | sourceTree = "";
137 | };
138 | 438B396F6B4147076630CAEFE34282C1 /* iOS */ = {
139 | isa = PBXGroup;
140 | children = (
141 | D88AAE1F92055A60CC2FC970D7D34634 /* Foundation.framework */,
142 | B63C6A64CF66340668996F78DA6BB482 /* UIKit.framework */,
143 | );
144 | name = iOS;
145 | sourceTree = "";
146 | };
147 | 4DC29A2E985102ABF89929CB799C46BA /* Pod */ = {
148 | isa = PBXGroup;
149 | children = (
150 | 725B0B9E990130908A56251D75A483BA /* LICENSE */,
151 | 2114385887C3BC99E5382E89DB279F5F /* LJRouter.podspec */,
152 | 3C08F10EA3A8140D98270A2A0C60A9A3 /* README.md */,
153 | );
154 | name = Pod;
155 | sourceTree = "";
156 | };
157 | 5ADEED61D1E238C3A714D2C1D8538473 /* Support Files */ = {
158 | isa = PBXGroup;
159 | children = (
160 | AAACCE311E62A263051AB128115292BE /* LJRouter.xcconfig */,
161 | CB871749505B51AFD97BFC6EB727B6C4 /* LJRouter-dummy.m */,
162 | 84BBA6949276A6302B39B74608EC7FEC /* LJRouter-prefix.pch */,
163 | );
164 | name = "Support Files";
165 | path = "Example/Pods/Target Support Files/LJRouter";
166 | sourceTree = "";
167 | };
168 | 69549B099D10D084F39C65CB612EDF2C /* Targets Support Files */ = {
169 | isa = PBXGroup;
170 | children = (
171 | DACA5DF623DB6EF3F8699DF4EBACB3F1 /* Pods-LJRouter_Example */,
172 | );
173 | name = "Targets Support Files";
174 | sourceTree = "";
175 | };
176 | 7DB346D0F39D3F0E887471402A8071AB = {
177 | isa = PBXGroup;
178 | children = (
179 | 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */,
180 | 0486F50E18EADC01A0D32B4277F7EAB1 /* Development Pods */,
181 | 433CD3331B6C3787F473C941B61FC68F /* Frameworks */,
182 | D56E717310B2DEF877F1C6850453CE8D /* Products */,
183 | 69549B099D10D084F39C65CB612EDF2C /* Targets Support Files */,
184 | );
185 | sourceTree = "";
186 | };
187 | D56E717310B2DEF877F1C6850453CE8D /* Products */ = {
188 | isa = PBXGroup;
189 | children = (
190 | 193344E2033F65E4E73190FB2BF8DCBF /* libLJRouter.a */,
191 | 0FB445BF0199E908BD39EB33182BF612 /* libPods-LJRouter_Example.a */,
192 | );
193 | name = Products;
194 | sourceTree = "";
195 | };
196 | DACA5DF623DB6EF3F8699DF4EBACB3F1 /* Pods-LJRouter_Example */ = {
197 | isa = PBXGroup;
198 | children = (
199 | F11DDBA8BE62EBF7D9BD808D482E89AF /* Pods-LJRouter_Example-acknowledgements.markdown */,
200 | BC58743EFF4E5237B7926C81B6AE3BC4 /* Pods-LJRouter_Example-acknowledgements.plist */,
201 | C424084C8EE1138C637D11025DC793B1 /* Pods-LJRouter_Example-dummy.m */,
202 | 33A0E83796DA88F4DC8F1B87B3E90A7F /* Pods-LJRouter_Example-frameworks.sh */,
203 | 9B149CCA91703BAB29C101853F2D873A /* Pods-LJRouter_Example-resources.sh */,
204 | 8AEC40840BA9158D5D389CA324D2121C /* Pods-LJRouter_Example.debug.xcconfig */,
205 | 979AAAC514FB32C539F5C84B7155C1CC /* Pods-LJRouter_Example.release.xcconfig */,
206 | );
207 | name = "Pods-LJRouter_Example";
208 | path = "Target Support Files/Pods-LJRouter_Example";
209 | sourceTree = "";
210 | };
211 | ED4030E341AA953B088F68AD03BE2E28 /* Navigation */ = {
212 | isa = PBXGroup;
213 | children = (
214 | 9384EA1EC3F9F880AA95D9CAAB2448D8 /* UIViewController+LJNavigation.h */,
215 | 2F713603D0BC5DAC1825045E3C343A24 /* UIViewController+LJNavigation.m */,
216 | );
217 | name = Navigation;
218 | sourceTree = "";
219 | };
220 | /* End PBXGroup section */
221 |
222 | /* Begin PBXHeadersBuildPhase section */
223 | 83C5D3210F3CF4FDC085096DB36C51B2 /* Headers */ = {
224 | isa = PBXHeadersBuildPhase;
225 | buildActionMask = 2147483647;
226 | files = (
227 | E0BE10049AAC2890F685169DBA6ED71F /* LJInvocationCenter.h in Headers */,
228 | 48BF8C7DE9DBE5A20CD338741D476CBA /* LJRouter.h in Headers */,
229 | 729D3AFB73234094614EE8A20C565055 /* LJRouterConvertManager.h in Headers */,
230 | 23570B18BE6B1B9FFC424F8810669353 /* LJRouterPrivate.h in Headers */,
231 | 0083AD54101A8F2BC28D49D9EB763D0B /* LJUrlRouter.h in Headers */,
232 | 665FB8709EB20255F270B3BB34D88B82 /* metamacros.h in Headers */,
233 | 81440BE60992DE7F04E32F4D384C221C /* UIViewController+LJNavigation.h in Headers */,
234 | );
235 | runOnlyForDeploymentPostprocessing = 0;
236 | };
237 | /* End PBXHeadersBuildPhase section */
238 |
239 | /* Begin PBXNativeTarget section */
240 | 9BE377BC0EA4DBB3AC88A6EA7C749843 /* Pods-LJRouter_Example */ = {
241 | isa = PBXNativeTarget;
242 | buildConfigurationList = FFF5842AA7756556DD07A9693FE51BA1 /* Build configuration list for PBXNativeTarget "Pods-LJRouter_Example" */;
243 | buildPhases = (
244 | 74701A19B7519A6855751717AE747C0D /* Sources */,
245 | 6E8B39E1293010056503927B3CBAEA3E /* Frameworks */,
246 | );
247 | buildRules = (
248 | );
249 | dependencies = (
250 | 0DD79F3D5B150FBD99A244FBC7A4C242 /* PBXTargetDependency */,
251 | );
252 | name = "Pods-LJRouter_Example";
253 | productName = "Pods-LJRouter_Example";
254 | productReference = 0FB445BF0199E908BD39EB33182BF612 /* libPods-LJRouter_Example.a */;
255 | productType = "com.apple.product-type.library.static";
256 | };
257 | AEE6E99EB3157BC0AFF77C9FE07B7392 /* LJRouter */ = {
258 | isa = PBXNativeTarget;
259 | buildConfigurationList = F6E45B0BA338851D7B9DC734DF017CF1 /* Build configuration list for PBXNativeTarget "LJRouter" */;
260 | buildPhases = (
261 | 400A04FEA2C569C148F6560B387F67FF /* Sources */,
262 | 13A9F228798A263CBD90052D42D1A294 /* Frameworks */,
263 | 83C5D3210F3CF4FDC085096DB36C51B2 /* Headers */,
264 | );
265 | buildRules = (
266 | );
267 | dependencies = (
268 | );
269 | name = LJRouter;
270 | productName = LJRouter;
271 | productReference = 193344E2033F65E4E73190FB2BF8DCBF /* libLJRouter.a */;
272 | productType = "com.apple.product-type.library.static";
273 | };
274 | /* End PBXNativeTarget section */
275 |
276 | /* Begin PBXProject section */
277 | D41D8CD98F00B204E9800998ECF8427E /* Project object */ = {
278 | isa = PBXProject;
279 | attributes = {
280 | LastSwiftUpdateCheck = 0830;
281 | LastUpgradeCheck = 0700;
282 | };
283 | buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */;
284 | compatibilityVersion = "Xcode 3.2";
285 | developmentRegion = English;
286 | hasScannedForEncodings = 0;
287 | knownRegions = (
288 | en,
289 | );
290 | mainGroup = 7DB346D0F39D3F0E887471402A8071AB;
291 | productRefGroup = D56E717310B2DEF877F1C6850453CE8D /* Products */;
292 | projectDirPath = "";
293 | projectRoot = "";
294 | targets = (
295 | AEE6E99EB3157BC0AFF77C9FE07B7392 /* LJRouter */,
296 | 9BE377BC0EA4DBB3AC88A6EA7C749843 /* Pods-LJRouter_Example */,
297 | );
298 | };
299 | /* End PBXProject section */
300 |
301 | /* Begin PBXSourcesBuildPhase section */
302 | 400A04FEA2C569C148F6560B387F67FF /* Sources */ = {
303 | isa = PBXSourcesBuildPhase;
304 | buildActionMask = 2147483647;
305 | files = (
306 | C15B89E3AF780159CA74790D99D19DAE /* LJInvocationCenter.m in Sources */,
307 | 6731DAC759CA8658E123FB13446E536F /* LJRouter-dummy.m in Sources */,
308 | 6D0B910509F817D70D790C8B3805AF36 /* LJRouter.m in Sources */,
309 | 834C0829F0FE1DB8C77F46B8D06ABC05 /* LJRouterConvertManager.m in Sources */,
310 | 68518674328950BAF3BEC991415DEAD9 /* LJUrlRouter.m in Sources */,
311 | 8B0146414ECA1EA9F23A87BCEBDAA59D /* UIViewController+LJNavigation.m in Sources */,
312 | );
313 | runOnlyForDeploymentPostprocessing = 0;
314 | };
315 | 74701A19B7519A6855751717AE747C0D /* Sources */ = {
316 | isa = PBXSourcesBuildPhase;
317 | buildActionMask = 2147483647;
318 | files = (
319 | 1035915AE1C08B61DC1E9EF0E95B1FF8 /* Pods-LJRouter_Example-dummy.m in Sources */,
320 | );
321 | runOnlyForDeploymentPostprocessing = 0;
322 | };
323 | /* End PBXSourcesBuildPhase section */
324 |
325 | /* Begin PBXTargetDependency section */
326 | 0DD79F3D5B150FBD99A244FBC7A4C242 /* PBXTargetDependency */ = {
327 | isa = PBXTargetDependency;
328 | name = LJRouter;
329 | target = AEE6E99EB3157BC0AFF77C9FE07B7392 /* LJRouter */;
330 | targetProxy = B7187F05F56362033182C1726625EA75 /* PBXContainerItemProxy */;
331 | };
332 | /* End PBXTargetDependency section */
333 |
334 | /* Begin XCBuildConfiguration section */
335 | 01392668EFCA9EFBE01B4FFFD84AD6BB /* Release */ = {
336 | isa = XCBuildConfiguration;
337 | baseConfigurationReference = 979AAAC514FB32C539F5C84B7155C1CC /* Pods-LJRouter_Example.release.xcconfig */;
338 | buildSettings = {
339 | CODE_SIGN_IDENTITY = "iPhone Developer";
340 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
341 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
342 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
343 | IPHONEOS_DEPLOYMENT_TARGET = 8.3;
344 | MACH_O_TYPE = staticlib;
345 | OTHER_LDFLAGS = "";
346 | OTHER_LIBTOOLFLAGS = "";
347 | PODS_ROOT = "$(SRCROOT)";
348 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
349 | SDKROOT = iphoneos;
350 | SKIP_INSTALL = YES;
351 | TARGETED_DEVICE_FAMILY = "1,2";
352 | VALIDATE_PRODUCT = YES;
353 | };
354 | name = Release;
355 | };
356 | 0F6051798894915FAA72FAEBA4BB0132 /* Release */ = {
357 | isa = XCBuildConfiguration;
358 | baseConfigurationReference = AAACCE311E62A263051AB128115292BE /* LJRouter.xcconfig */;
359 | buildSettings = {
360 | CODE_SIGN_IDENTITY = "iPhone Developer";
361 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
362 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
363 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
364 | GCC_PREFIX_HEADER = "Target Support Files/LJRouter/LJRouter-prefix.pch";
365 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
366 | OTHER_LDFLAGS = "";
367 | OTHER_LIBTOOLFLAGS = "";
368 | PRIVATE_HEADERS_FOLDER_PATH = "";
369 | PUBLIC_HEADERS_FOLDER_PATH = "";
370 | SDKROOT = iphoneos;
371 | SKIP_INSTALL = YES;
372 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
373 | TARGETED_DEVICE_FAMILY = "1,2";
374 | VALIDATE_PRODUCT = YES;
375 | };
376 | name = Release;
377 | };
378 | 1CDAB5613991E411E5990BAF694995C5 /* Debug */ = {
379 | isa = XCBuildConfiguration;
380 | buildSettings = {
381 | ALWAYS_SEARCH_USER_PATHS = NO;
382 | CLANG_ANALYZER_NONNULL = YES;
383 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
384 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
385 | CLANG_CXX_LIBRARY = "libc++";
386 | CLANG_ENABLE_MODULES = YES;
387 | CLANG_ENABLE_OBJC_ARC = YES;
388 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
389 | CLANG_WARN_BOOL_CONVERSION = YES;
390 | CLANG_WARN_COMMA = YES;
391 | CLANG_WARN_CONSTANT_CONVERSION = YES;
392 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
393 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
394 | CLANG_WARN_EMPTY_BODY = YES;
395 | CLANG_WARN_ENUM_CONVERSION = YES;
396 | CLANG_WARN_INFINITE_RECURSION = YES;
397 | CLANG_WARN_INT_CONVERSION = YES;
398 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
399 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
400 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
401 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
402 | CLANG_WARN_STRICT_PROTOTYPES = YES;
403 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
404 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
405 | CLANG_WARN_UNREACHABLE_CODE = YES;
406 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
407 | CODE_SIGNING_REQUIRED = NO;
408 | COPY_PHASE_STRIP = NO;
409 | DEBUG_INFORMATION_FORMAT = dwarf;
410 | ENABLE_STRICT_OBJC_MSGSEND = YES;
411 | ENABLE_TESTABILITY = YES;
412 | GCC_C_LANGUAGE_STANDARD = gnu11;
413 | GCC_DYNAMIC_NO_PIC = NO;
414 | GCC_NO_COMMON_BLOCKS = YES;
415 | GCC_OPTIMIZATION_LEVEL = 0;
416 | GCC_PREPROCESSOR_DEFINITIONS = (
417 | "POD_CONFIGURATION_DEBUG=1",
418 | "DEBUG=1",
419 | "$(inherited)",
420 | );
421 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
422 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
423 | GCC_WARN_UNDECLARED_SELECTOR = YES;
424 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
425 | GCC_WARN_UNUSED_FUNCTION = YES;
426 | GCC_WARN_UNUSED_VARIABLE = YES;
427 | IPHONEOS_DEPLOYMENT_TARGET = 8.3;
428 | MTL_ENABLE_DEBUG_INFO = YES;
429 | ONLY_ACTIVE_ARCH = YES;
430 | PRODUCT_NAME = "$(TARGET_NAME)";
431 | PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/;
432 | STRIP_INSTALLED_PRODUCT = NO;
433 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
434 | SYMROOT = "${SRCROOT}/../build";
435 | };
436 | name = Debug;
437 | };
438 | 7B62A85C412D689EF418FA67DA770A41 /* Release */ = {
439 | isa = XCBuildConfiguration;
440 | buildSettings = {
441 | ALWAYS_SEARCH_USER_PATHS = NO;
442 | CLANG_ANALYZER_NONNULL = YES;
443 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
444 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
445 | CLANG_CXX_LIBRARY = "libc++";
446 | CLANG_ENABLE_MODULES = YES;
447 | CLANG_ENABLE_OBJC_ARC = YES;
448 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
449 | CLANG_WARN_BOOL_CONVERSION = YES;
450 | CLANG_WARN_COMMA = YES;
451 | CLANG_WARN_CONSTANT_CONVERSION = YES;
452 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
453 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
454 | CLANG_WARN_EMPTY_BODY = YES;
455 | CLANG_WARN_ENUM_CONVERSION = YES;
456 | CLANG_WARN_INFINITE_RECURSION = YES;
457 | CLANG_WARN_INT_CONVERSION = YES;
458 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
459 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
460 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
461 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
462 | CLANG_WARN_STRICT_PROTOTYPES = YES;
463 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
464 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
465 | CLANG_WARN_UNREACHABLE_CODE = YES;
466 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
467 | CODE_SIGNING_REQUIRED = NO;
468 | COPY_PHASE_STRIP = NO;
469 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
470 | ENABLE_NS_ASSERTIONS = NO;
471 | ENABLE_STRICT_OBJC_MSGSEND = YES;
472 | GCC_C_LANGUAGE_STANDARD = gnu11;
473 | GCC_NO_COMMON_BLOCKS = YES;
474 | GCC_PREPROCESSOR_DEFINITIONS = (
475 | "POD_CONFIGURATION_RELEASE=1",
476 | "$(inherited)",
477 | );
478 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
479 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
480 | GCC_WARN_UNDECLARED_SELECTOR = YES;
481 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
482 | GCC_WARN_UNUSED_FUNCTION = YES;
483 | GCC_WARN_UNUSED_VARIABLE = YES;
484 | IPHONEOS_DEPLOYMENT_TARGET = 8.3;
485 | MTL_ENABLE_DEBUG_INFO = NO;
486 | PRODUCT_NAME = "$(TARGET_NAME)";
487 | PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/;
488 | STRIP_INSTALLED_PRODUCT = NO;
489 | SYMROOT = "${SRCROOT}/../build";
490 | };
491 | name = Release;
492 | };
493 | A0A6659BD2C883ADC52FB0FFB96DC083 /* Debug */ = {
494 | isa = XCBuildConfiguration;
495 | baseConfigurationReference = AAACCE311E62A263051AB128115292BE /* LJRouter.xcconfig */;
496 | buildSettings = {
497 | CODE_SIGN_IDENTITY = "iPhone Developer";
498 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
499 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
500 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
501 | GCC_PREFIX_HEADER = "Target Support Files/LJRouter/LJRouter-prefix.pch";
502 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
503 | OTHER_LDFLAGS = "";
504 | OTHER_LIBTOOLFLAGS = "";
505 | PRIVATE_HEADERS_FOLDER_PATH = "";
506 | PUBLIC_HEADERS_FOLDER_PATH = "";
507 | SDKROOT = iphoneos;
508 | SKIP_INSTALL = YES;
509 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) ";
510 | TARGETED_DEVICE_FAMILY = "1,2";
511 | };
512 | name = Debug;
513 | };
514 | F5472DC2E0D14C0AC6401A886174AEC8 /* Debug */ = {
515 | isa = XCBuildConfiguration;
516 | baseConfigurationReference = 8AEC40840BA9158D5D389CA324D2121C /* Pods-LJRouter_Example.debug.xcconfig */;
517 | buildSettings = {
518 | CODE_SIGN_IDENTITY = "iPhone Developer";
519 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
520 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
521 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
522 | IPHONEOS_DEPLOYMENT_TARGET = 8.3;
523 | MACH_O_TYPE = staticlib;
524 | OTHER_LDFLAGS = "";
525 | OTHER_LIBTOOLFLAGS = "";
526 | PODS_ROOT = "$(SRCROOT)";
527 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}";
528 | SDKROOT = iphoneos;
529 | SKIP_INSTALL = YES;
530 | TARGETED_DEVICE_FAMILY = "1,2";
531 | };
532 | name = Debug;
533 | };
534 | /* End XCBuildConfiguration section */
535 |
536 | /* Begin XCConfigurationList section */
537 | 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = {
538 | isa = XCConfigurationList;
539 | buildConfigurations = (
540 | 1CDAB5613991E411E5990BAF694995C5 /* Debug */,
541 | 7B62A85C412D689EF418FA67DA770A41 /* Release */,
542 | );
543 | defaultConfigurationIsVisible = 0;
544 | defaultConfigurationName = Release;
545 | };
546 | F6E45B0BA338851D7B9DC734DF017CF1 /* Build configuration list for PBXNativeTarget "LJRouter" */ = {
547 | isa = XCConfigurationList;
548 | buildConfigurations = (
549 | A0A6659BD2C883ADC52FB0FFB96DC083 /* Debug */,
550 | 0F6051798894915FAA72FAEBA4BB0132 /* Release */,
551 | );
552 | defaultConfigurationIsVisible = 0;
553 | defaultConfigurationName = Release;
554 | };
555 | FFF5842AA7756556DD07A9693FE51BA1 /* Build configuration list for PBXNativeTarget "Pods-LJRouter_Example" */ = {
556 | isa = XCConfigurationList;
557 | buildConfigurations = (
558 | F5472DC2E0D14C0AC6401A886174AEC8 /* Debug */,
559 | 01392668EFCA9EFBE01B4FFFD84AD6BB /* Release */,
560 | );
561 | defaultConfigurationIsVisible = 0;
562 | defaultConfigurationName = Release;
563 | };
564 | /* End XCConfigurationList section */
565 | };
566 | rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */;
567 | }
568 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/LJRouter/LJRouter-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_LJRouter : NSObject
3 | @end
4 | @implementation PodsDummy_LJRouter
5 | @end
6 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/LJRouter/LJRouter-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/LJRouter/LJRouter.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/LJRouter
2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/LJRouter" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/LJRouter"
4 | OTHER_LDFLAGS = -framework "UIKit"
5 | PODS_BUILD_DIR = ${BUILD_DIR}
6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_ROOT = ${SRCROOT}
8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
10 | SKIP_INSTALL = YES
11 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-LJRouter_Example/Pods-LJRouter_Example-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 |
4 | ## LJRouter
5 |
6 | MIT License
7 |
8 | Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
9 |
10 | Permission is hereby granted, free of charge, to any person obtaining a copy
11 | of this software and associated documentation files (the "Software"), to deal
12 | in the Software without restriction, including without limitation the rights
13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 | copies of the Software, and to permit persons to whom the Software is
15 | furnished to do so, subject to the following conditions:
16 |
17 | The above copyright notice and this permission notice shall be included in
18 | all copies or substantial portions of the Software.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 | THE SOFTWARE.
27 |
28 | Generated by CocoaPods - https://cocoapods.org
29 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-LJRouter_Example/Pods-LJRouter_Example-acknowledgements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreferenceSpecifiers
6 |
7 |
8 | FooterText
9 | This application makes use of the following third party libraries:
10 | Title
11 | Acknowledgements
12 | Type
13 | PSGroupSpecifier
14 |
15 |
16 | FooterText
17 | MIT License
18 |
19 | Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
20 |
21 | Permission is hereby granted, free of charge, to any person obtaining a copy
22 | of this software and associated documentation files (the "Software"), to deal
23 | in the Software without restriction, including without limitation the rights
24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
25 | copies of the Software, and to permit persons to whom the Software is
26 | furnished to do so, subject to the following conditions:
27 |
28 | The above copyright notice and this permission notice shall be included in
29 | all copies or substantial portions of the Software.
30 |
31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
37 | THE SOFTWARE.
38 |
39 | License
40 | MIT
41 | Title
42 | LJRouter
43 | Type
44 | PSGroupSpecifier
45 |
46 |
47 | FooterText
48 | Generated by CocoaPods - https://cocoapods.org
49 | Title
50 |
51 | Type
52 | PSGroupSpecifier
53 |
54 |
55 | StringsTable
56 | Acknowledgements
57 | Title
58 | Acknowledgements
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-LJRouter_Example/Pods-LJRouter_Example-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_LJRouter_Example : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_LJRouter_Example
5 | @end
6 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-LJRouter_Example/Pods-LJRouter_Example-frameworks.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
6 |
7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
8 |
9 | # Used as a return value for each invocation of `strip_invalid_archs` function.
10 | STRIP_BINARY_RETVAL=0
11 |
12 | # This protects against multiple targets copying the same framework dependency at the same time. The solution
13 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
14 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
15 |
16 | # Copies and strips a vendored framework
17 | install_framework()
18 | {
19 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
20 | local source="${BUILT_PRODUCTS_DIR}/$1"
21 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then
22 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")"
23 | elif [ -r "$1" ]; then
24 | local source="$1"
25 | fi
26 |
27 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
28 |
29 | if [ -L "${source}" ]; then
30 | echo "Symlinked..."
31 | source="$(readlink "${source}")"
32 | fi
33 |
34 | # Use filter instead of exclude so missing patterns don't throw errors.
35 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
36 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
37 |
38 | local basename
39 | basename="$(basename -s .framework "$1")"
40 | binary="${destination}/${basename}.framework/${basename}"
41 | if ! [ -r "$binary" ]; then
42 | binary="${destination}/${basename}"
43 | fi
44 |
45 | # Strip invalid architectures so "fat" simulator / device frameworks work on device
46 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then
47 | strip_invalid_archs "$binary"
48 | fi
49 |
50 | # Resign the code if required by the build settings to avoid unstable apps
51 | code_sign_if_enabled "${destination}/$(basename "$1")"
52 |
53 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7.
54 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then
55 | local swift_runtime_libs
56 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]})
57 | for lib in $swift_runtime_libs; do
58 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\""
59 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}"
60 | code_sign_if_enabled "${destination}/${lib}"
61 | done
62 | fi
63 | }
64 |
65 | # Copies and strips a vendored dSYM
66 | install_dsym() {
67 | local source="$1"
68 | if [ -r "$source" ]; then
69 | # Copy the dSYM into a the targets temp dir.
70 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
71 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
72 |
73 | local basename
74 | basename="$(basename -s .framework.dSYM "$source")"
75 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}"
76 |
77 | # Strip invalid architectures so "fat" simulator / device frameworks work on device
78 | if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then
79 | strip_invalid_archs "$binary"
80 | fi
81 |
82 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
83 | # Move the stripped file into its final destination.
84 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
85 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
86 | else
87 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
88 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM"
89 | fi
90 | fi
91 | }
92 |
93 | # Signs a framework with the provided identity
94 | code_sign_if_enabled() {
95 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then
96 | # Use the current code_sign_identitiy
97 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
98 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'"
99 |
100 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
101 | code_sign_cmd="$code_sign_cmd &"
102 | fi
103 | echo "$code_sign_cmd"
104 | eval "$code_sign_cmd"
105 | fi
106 | }
107 |
108 | # Strip invalid architectures
109 | strip_invalid_archs() {
110 | binary="$1"
111 | # Get architectures for current target binary
112 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
113 | # Intersect them with the architectures we are building for
114 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
115 | # If there are no archs supported by this binary then warn the user
116 | if [[ -z "$intersected_archs" ]]; then
117 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
118 | STRIP_BINARY_RETVAL=0
119 | return
120 | fi
121 | stripped=""
122 | for arch in $binary_archs; do
123 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then
124 | # Strip non-valid architectures in-place
125 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1
126 | stripped="$stripped $arch"
127 | fi
128 | done
129 | if [[ "$stripped" ]]; then
130 | echo "Stripped $binary of architectures:$stripped"
131 | fi
132 | STRIP_BINARY_RETVAL=1
133 | }
134 |
135 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
136 | wait
137 | fi
138 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-LJRouter_Example/Pods-LJRouter_Example-resources.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
5 |
6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
7 | > "$RESOURCES_TO_COPY"
8 |
9 | XCASSET_FILES=()
10 |
11 | # This protects against multiple targets copying the same framework dependency at the same time. The solution
12 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
13 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
14 |
15 | case "${TARGETED_DEVICE_FAMILY}" in
16 | 1,2)
17 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone"
18 | ;;
19 | 1)
20 | TARGET_DEVICE_ARGS="--target-device iphone"
21 | ;;
22 | 2)
23 | TARGET_DEVICE_ARGS="--target-device ipad"
24 | ;;
25 | 3)
26 | TARGET_DEVICE_ARGS="--target-device tv"
27 | ;;
28 | 4)
29 | TARGET_DEVICE_ARGS="--target-device watch"
30 | ;;
31 | *)
32 | TARGET_DEVICE_ARGS="--target-device mac"
33 | ;;
34 | esac
35 |
36 | install_resource()
37 | {
38 | if [[ "$1" = /* ]] ; then
39 | RESOURCE_PATH="$1"
40 | else
41 | RESOURCE_PATH="${PODS_ROOT}/$1"
42 | fi
43 | if [[ ! -e "$RESOURCE_PATH" ]] ; then
44 | cat << EOM
45 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script.
46 | EOM
47 | exit 1
48 | fi
49 | case $RESOURCE_PATH in
50 | *.storyboard)
51 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
52 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
53 | ;;
54 | *.xib)
55 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
56 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
57 | ;;
58 | *.framework)
59 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
60 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
61 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
62 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
63 | ;;
64 | *.xcdatamodel)
65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true
66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
67 | ;;
68 | *.xcdatamodeld)
69 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true
70 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
71 | ;;
72 | *.xcmappingmodel)
73 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true
74 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
75 | ;;
76 | *.xcassets)
77 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH"
78 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
79 | ;;
80 | *)
81 | echo "$RESOURCE_PATH" || true
82 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
83 | ;;
84 | esac
85 | }
86 |
87 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
88 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
89 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then
90 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
91 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
92 | fi
93 | rm -f "$RESOURCES_TO_COPY"
94 |
95 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ]
96 | then
97 | # Find all other xcassets (this unfortunately includes those of path pods and other targets).
98 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
99 | while read line; do
100 | if [[ $line != "${PODS_ROOT}*" ]]; then
101 | XCASSET_FILES+=("$line")
102 | fi
103 | done <<<"$OTHER_XCASSETS"
104 |
105 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
106 | fi
107 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-LJRouter_Example/Pods-LJRouter_Example.debug.xcconfig:
--------------------------------------------------------------------------------
1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/LJRouter"
3 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/LJRouter"
4 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/LJRouter"
5 | OTHER_LDFLAGS = $(inherited) -ObjC -l"LJRouter" -framework "UIKit"
6 | PODS_BUILD_DIR = ${BUILD_DIR}
7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
9 | PODS_ROOT = ${SRCROOT}/Pods
10 |
--------------------------------------------------------------------------------
/Example/Pods/Target Support Files/Pods-LJRouter_Example/Pods-LJRouter_Example.release.xcconfig:
--------------------------------------------------------------------------------
1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/LJRouter"
3 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/LJRouter"
4 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/LJRouter"
5 | OTHER_LDFLAGS = $(inherited) -ObjC -l"LJRouter" -framework "UIKit"
6 | PODS_BUILD_DIR = ${BUILD_DIR}
7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
9 | PODS_ROOT = ${SRCROOT}/Pods
10 |
--------------------------------------------------------------------------------
/Example/outputHeaders/LJHomeComponentHeader.h:
--------------------------------------------------------------------------------
1 | // 页面 : 首页tabbar
2 | LJRouterUsePage(homeTabbar);
3 | // 页面 : 2017年新版首页
4 | LJRouterUsePage(Home, (NSString*)titlex);
5 | // 页面 : 泛型测试
6 | LJRouterUsePage(objectTypeTest, (NSDictionary*)aaa);
7 |
--------------------------------------------------------------------------------
/Example/outputHeaders/LJLoginComponentHeader.h:
--------------------------------------------------------------------------------
1 | // 页面 : 登录页面
2 | LJRouterUsePage(login);
3 | // action : 判断登录状态,弹出登录页面
4 | LJRouterUseAction(loginIfNeed, void, (UIViewController*)curVC, (void(^)(BOOL))finishBlock);
5 | // action : 是否登录状态
6 | LJRouterUseAction(isLogin, BOOL);
7 | // action : 退出登录
8 | LJRouterUseAction(logout, void);
9 |
--------------------------------------------------------------------------------
/Example/outputHeaders/LJPersonalComponentHeader.h:
--------------------------------------------------------------------------------
1 | // 页面 : 设置页面
2 | LJRouterUsePage(setting);
3 | // 页面 : 我的个人页
4 | LJRouterUsePage(myProfile, (unsigned long)userId);
5 | // 页面 : 个人页
6 | LJRouterUsePage(myProfile, (NSDictionary*)user);
7 |
--------------------------------------------------------------------------------
/Example/outputHeaders/LJWebviewComponentHeader.h:
--------------------------------------------------------------------------------
1 | // 页面 : webview
2 | LJRouterUsePage(webview, (NSString*)url);
3 | // 页面 : webview
4 | LJRouterUsePage(webview, (NSString*)htmlString);
5 | // action : 接收js命令
6 | // 接收一个字符串 添加_haha结尾
7 | LJRouterUseAction(somejscmd, void, (NSString*)str, (LJRouterCallbackBlock)callback);
8 | // action : 设置UIWebView标题
9 | LJRouterUseAction(setWebViewTitle, void, (UIWebView*)sender, (NSString*)title);
10 | // action : 设置UIWebView标题
11 | LJRouterUseAction(setWebViewTitle2, void, (LJRouterSenderContext*)sender, (NSString*)title);
12 |
--------------------------------------------------------------------------------
/Example/outputHeaders/action.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "key" : "somejscmd",
4 | "actionDesc" : "接收js命令\/\/ 接收一个字符串 添加_haha结尾",
5 | "parameters" : [
6 | {
7 | "name" : "str"
8 | },
9 | {
10 | "name" : "callback"
11 | }
12 | ]
13 | },
14 | {
15 | "key" : "setWebViewTitle",
16 | "actionDesc" : "设置UIWebView标题",
17 | "parameters" : [
18 | {
19 | "name" : "sender"
20 | },
21 | {
22 | "name" : "title"
23 | }
24 | ]
25 | },
26 | {
27 | "key" : "setWebViewTitle2",
28 | "actionDesc" : "设置UIWebView标题",
29 | "parameters" : [
30 | {
31 | "name" : "sender"
32 | },
33 | {
34 | "name" : "title"
35 | }
36 | ]
37 | },
38 | {
39 | "key" : "loginIfNeed",
40 | "actionDesc" : "判断登录状态,弹出登录页面",
41 | "parameters" : [
42 | {
43 | "name" : "curVC"
44 | },
45 | {
46 | "name" : "finishBlock"
47 | }
48 | ]
49 | },
50 | {
51 | "key" : "isLogin",
52 | "actionDesc" : "是否登录状态",
53 | "parameters" : [
54 |
55 | ]
56 | },
57 | {
58 | "key" : "logout",
59 | "actionDesc" : "退出登录",
60 | "parameters" : [
61 |
62 | ]
63 | }
64 | ]
--------------------------------------------------------------------------------
/Example/outputHeaders/page.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "key" : "homeTabbar",
4 | "actionDesc" : "首页tabbar",
5 | "parameters" : [
6 |
7 | ]
8 | },
9 | {
10 | "key" : "webview",
11 | "actionDesc" : "webview",
12 | "parameters" : [
13 | {
14 | "name" : "url"
15 | }
16 | ]
17 | },
18 | {
19 | "key" : "webview",
20 | "actionDesc" : "webview",
21 | "parameters" : [
22 | {
23 | "name" : "htmlString"
24 | }
25 | ]
26 | },
27 | {
28 | "key" : "Home",
29 | "actionDesc" : "2017年新版首页",
30 | "parameters" : [
31 | {
32 | "name" : "titlex"
33 | }
34 | ]
35 | },
36 | {
37 | "key" : "objectTypeTest",
38 | "actionDesc" : "泛型测试",
39 | "parameters" : [
40 | {
41 | "name" : "aaa"
42 | }
43 | ]
44 | },
45 | {
46 | "key" : "setting",
47 | "actionDesc" : "设置页面",
48 | "parameters" : [
49 |
50 | ]
51 | },
52 | {
53 | "key" : "myProfile",
54 | "actionDesc" : "我的个人页",
55 | "parameters" : [
56 | {
57 | "name" : "userId"
58 | }
59 | ]
60 | },
61 | {
62 | "key" : "myProfile",
63 | "actionDesc" : "个人页",
64 | "parameters" : [
65 | {
66 | "name" : "user"
67 | }
68 | ]
69 | },
70 | {
71 | "key" : "login",
72 | "actionDesc" : "登录页面",
73 | "parameters" : [
74 |
75 | ]
76 | }
77 | ]
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LJRouter.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'LJRouter'
3 | s.version = '0.7.0'
4 | s.summary = '链家iOS路由方案'
5 | s.description = <<-DESC
6 | LJRouter是链家独立开发完成的ios客户端路由跳转模块,该模块在接入,安全性,易用性都有比较好的表现,一行代码即可支持h5交互,push跳转,url scheme跳转等功能并实时生成文档.
7 | DESC
8 | s.homepage = 'https://github.com/LianjiaTech/LJRouter'
9 | s.license = { :type => 'MIT', :file => 'LICENSE' }
10 | s.author = { 'chenxi' => 'fover0@126.com' }
11 | s.source = { :git => "https://github.com/LianjiaTech/LJRouter.git",:tag => "#{s.version}"}
12 |
13 | s.preserve_path = 'LJRouter/ExportTool','LJRouter/ExportDocument','build'
14 | s.platform = :ios
15 | s.ios.framework = 'UIKit'
16 | s.ios.deployment_target = '8.0'
17 |
18 | s.subspec 'Core' do |ss|
19 | ss.source_files = 'LJRouter/Core/**/*'
20 | end
21 |
22 | s.subspec 'Navigation' do |ss|
23 | ss.source_files = 'LJRouter/Navigation/**/*'
24 | end
25 |
26 | s.default_subspec = 'Core','Navigation'
27 |
28 | end
29 |
--------------------------------------------------------------------------------
/LJRouter/Core/LJInvocationCenter.h:
--------------------------------------------------------------------------------
1 | //
2 | // LJInvocationCenter.h
3 | // IM
4 | //
5 | // Created by fover0 on 2017/5/28.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | #import
10 | #import "LJRouterConvertManager.h"
11 |
12 |
13 | // 参数描述
14 | @interface LJInvocationCenterItemParam : NSObject
15 |
16 | @property (nonatomic, readonly) BOOL isRequire;
17 | @property (nonatomic, readonly) NSString *name;
18 | @property (nonatomic, readonly) NSString *typeName;
19 | @property (nonatomic, readonly) NSString *typeEncoding;
20 | @property (nonatomic, readonly) id info;
21 |
22 | // lazy create NSArray* objcClass is NSArray objectTypes is [NSString]
23 | @property (nonatomic, readonly) Class objcClass;
24 | @property (nonatomic, readonly) NSArray *objectTypes;
25 |
26 |
27 | - (instancetype)initWithName:(NSString*)name
28 | typeName:(NSString*)typeName
29 | typeEncoding:(NSString*)typeEncoding
30 | isRequire:(BOOL)isRequire
31 | info:(id)info;
32 | @end
33 |
34 | // 函数重载描述
35 | @interface LJInvocationCenterItemRule : NSObject
36 | @property (nonatomic, readonly) SEL selector;
37 | @property (nonatomic, readonly) NSString *returnTypeName;
38 | @property (nonatomic, readonly) NSString *returnTypeEncoding;
39 | @property (nonatomic, readonly) NSArray* paramas;
40 |
41 | - (instancetype)initWithSelector:(SEL)selector
42 | returnTypeName:(NSString*)returnTypeName
43 | returnTypeEncoding:(NSString*)returnTypeEncoding
44 | params:(NSArray*)params;
45 |
46 | @end
47 |
48 | // 函数描述
49 | @interface LJInvocationCenterItem : NSObject
50 |
51 | @property (nonatomic, readonly) NSString *key;
52 | @property (nonatomic, readonly) id target;
53 | @property (nonatomic, readonly) NSArray *rules;
54 |
55 | @end
56 |
57 | // 转发中心
58 | @interface LJInvocationCenter : NSObject
59 |
60 | @property (nonatomic, retain) LJRouterConvertManager *convertManager;
61 |
62 | - (LJInvocationCenterItem*)getInvocationCenterItemByKey:(NSString*)key;
63 |
64 | - (void)addInvocationWithKey:(NSString*)key
65 | target:(id)target
66 | rule:(LJInvocationCenterItemRule*)rule;
67 |
68 | - (NSInvocation*)invocationWithKey:(NSString*)key
69 | data:(NSDictionary*)data
70 | outItem:(LJInvocationCenterItem**)outItem
71 | outRule:(LJInvocationCenterItemRule**)outRule;
72 |
73 | @end
74 |
--------------------------------------------------------------------------------
/LJRouter/Core/LJInvocationCenter.m:
--------------------------------------------------------------------------------
1 | //
2 | // LJInvocationCenter.m
3 | // IM
4 | //
5 | // Created by fover0 on 2017/5/28.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | #import "LJInvocationCenter.h"
10 | #import
11 | #import
12 |
13 | @interface LJInvocationCenterItemParam()
14 | {
15 | BOOL _classLazyLoadFinish;
16 | }
17 | @end
18 |
19 | @implementation LJInvocationCenterItemParam
20 | @synthesize objcClass = _objcClass;
21 | @synthesize objectTypes = _objectTypes;
22 |
23 | - (instancetype)initWithName:(NSString *)name
24 | typeName:(NSString *)typpName
25 | typeEncoding:(NSString *)typeEncoding
26 | isRequire:(BOOL)isRequire
27 | info:(id)info
28 | {
29 | self = [super init];
30 | if (self)
31 | {
32 | _classLazyLoadFinish = NO;
33 | _name = [name copy];
34 | _typeName = [typpName copy];
35 | _typeEncoding = [typeEncoding copy];
36 | _isRequire = isRequire;
37 | _info = info;
38 |
39 | _objcClass = Nil;
40 | _objectTypes = nil;
41 | }
42 | return self;
43 | }
44 |
45 | - (void)findObjectTypesInString:(NSString*)str
46 | outTypeNames:(NSArray**)outTypeNames
47 | outTypeEncoding:(NSArray**)outTypeEncodings
48 | {
49 | NSRange range;
50 | NSInteger stackCount = 0;
51 | NSInteger beginIndex = 0;
52 | NSString *typeEncoding = @"@";
53 | NSMutableArray *_outTypeNames = nil;
54 | NSMutableArray *_outTypeEncodings = nil;
55 | for(int i = 0 ; i < str.length; i += range.length)
56 | {
57 | range = [str rangeOfComposedCharacterSequenceAtIndex:i];
58 | if (range.length == 1)
59 | {
60 | NSString *s = [str substringWithRange:range];
61 | if ([s isEqualToString:@"<"]
62 | || [s isEqualToString:@"("]
63 | || [s isEqualToString:@"["]
64 | || [s isEqualToString:@"{"])
65 | {
66 | stackCount ++;
67 | }
68 | if ([s isEqualToString:@">"]
69 | || [s isEqualToString:@")"]
70 | || [s isEqualToString:@"]"]
71 | || [s isEqualToString:@"}"])
72 | {
73 | stackCount --;
74 | }
75 |
76 | if (stackCount == 0)
77 | {
78 | NSString *typeName = nil;
79 | if ([s isEqualToString:@","])
80 | {
81 | typeName = [str substringWithRange:NSMakeRange(beginIndex, range.location - beginIndex)];
82 |
83 |
84 | }
85 | else if (range.length + range.location == str.length)
86 | {
87 | typeName = [str substringFromIndex:beginIndex];
88 | }
89 | else if ([s isEqualToString:@"^"])
90 | {
91 | typeEncoding = @"?";
92 | }
93 |
94 | if (typeName)
95 | {
96 | if (!_outTypeNames)
97 | {
98 | _outTypeNames = [[NSMutableArray alloc] init];
99 | _outTypeEncodings = [[NSMutableArray alloc] init];
100 | if (outTypeNames)
101 | {
102 | *outTypeNames = _outTypeNames;
103 | *outTypeEncodings = _outTypeEncodings;
104 | }
105 | }
106 | [_outTypeNames addObject:typeName];
107 | [_outTypeEncodings addObject:typeEncoding];
108 | typeEncoding = @"@";
109 | beginIndex = range.location + 1;
110 | }
111 | }
112 | }
113 | }
114 | }
115 |
116 |
117 | - (void)lazyloadClassAndObjectTypes
118 | {
119 | if (_classLazyLoadFinish)
120 | {
121 | return;
122 | }
123 | @synchronized(self) {
124 | if (_classLazyLoadFinish)
125 | {
126 | return;
127 | }
128 |
129 | if (![self.typeEncoding isEqualToString:@"@"])
130 | {
131 | return;
132 | }
133 |
134 | NSMutableArray *objectTypesArray = nil;
135 |
136 | NSRange range = [self.typeName rangeOfString:@"<"];
137 | if (range.length)
138 | {
139 | NSRange endRange = [self.typeName rangeOfString:@">" options:NSBackwardsSearch];
140 | if (endRange.length)
141 | {
142 | NSString *startStr = [self.typeName substringToIndex:range.location];
143 | _objcClass = NSClassFromString(startStr);
144 | if (_objcClass)
145 | {
146 | NSString *objectTypesString = [self.typeName substringWithRange:NSMakeRange(range.location + 1, endRange.location - range.location - 1 )];
147 | NSArray *typeNames = nil;
148 | NSArray *typeEncoding = nil;
149 | [self findObjectTypesInString:objectTypesString
150 | outTypeNames:&typeNames
151 | outTypeEncoding:&typeEncoding];
152 | for (NSInteger i = 0 ; i < typeNames.count ; i ++)
153 | {
154 | LJInvocationCenterItemParam *param =
155 | [[LJInvocationCenterItemParam alloc] initWithName:@""
156 | typeName:typeNames[i]
157 | typeEncoding:typeEncoding[i]
158 | isRequire:self.isRequire
159 | info:self.info];
160 | if (objectTypesArray == nil)
161 | {
162 | objectTypesArray = [[NSMutableArray alloc] init];
163 | _objectTypes = objectTypesArray;
164 | }
165 | [objectTypesArray addObject:param];
166 | }
167 | }
168 | }
169 | }
170 | else
171 | {
172 | NSString *className = [self.typeName stringByReplacingOccurrencesOfString:@" " withString:@""];
173 | className = [className stringByReplacingOccurrencesOfString:@"*" withString:@""];
174 | _objcClass = NSClassFromString(className);
175 | }
176 | _classLazyLoadFinish = YES;
177 | }
178 | }
179 |
180 | - (Class)objcClass
181 | {
182 | [self lazyloadClassAndObjectTypes];
183 | return _objcClass;
184 | }
185 |
186 | - (NSArray*)objectTypes
187 | {
188 | [self lazyloadClassAndObjectTypes];
189 | return _objectTypes;
190 | }
191 |
192 | @end
193 |
194 | @implementation LJInvocationCenterItemRule
195 |
196 | - (instancetype)initWithSelector:(SEL)selector
197 | returnTypeName:(NSString *)returnTypeName
198 | returnTypeEncoding:(NSString *)returnTypeEncoding
199 | params:(NSArray *)params{
200 | self = [super init];
201 | if (self)
202 | {
203 | _selector = selector;
204 | _returnTypeName = [returnTypeName copy];
205 | _returnTypeEncoding = [returnTypeEncoding copy];
206 | _paramas = params;
207 |
208 | }
209 | return self;
210 | }
211 |
212 | @end
213 |
214 | @interface LJInvocationCenterItem()
215 | {
216 | NSMutableArray* _rules;
217 | __unsafe_unretained id unsafeTarget;
218 | id safeTarget;
219 | }
220 |
221 | @end
222 |
223 | @implementation LJInvocationCenterItem
224 |
225 | - (NSArray*)rules
226 | {
227 | return _rules;
228 | }
229 |
230 | - (instancetype)initWithKey:(NSString*)key target:(__unsafe_unretained id)target
231 | {
232 | self = [super init];
233 | if (self)
234 | {
235 | _rules = [[NSMutableArray alloc] init];
236 | _key = [key copy];
237 |
238 | Dl_info dlInfo;
239 | memset(&dlInfo, 0, sizeof(Dl_info));
240 | dladdr((__bridge void*)target, &dlInfo);
241 | if (object_isClass(target) && dlInfo.dli_fbase != 0)
242 | {
243 | unsafeTarget = target;
244 | safeTarget = Nil;
245 | }
246 | else
247 | {
248 | unsafeTarget = Nil;
249 | safeTarget = target;
250 | }
251 | }
252 | return self;
253 | }
254 |
255 | - (id)target
256 | {
257 | return unsafeTarget ? unsafeTarget : safeTarget;
258 | }
259 |
260 | - (void)addRule:(LJInvocationCenterItemRule*)rule
261 | {
262 | [_rules addObject:rule];
263 | }
264 |
265 | @end
266 |
267 | @interface LJInvocationCenter()
268 |
269 | @property (nonatomic, retain) NSMutableDictionary *allItem;
270 |
271 | @end
272 |
273 | @implementation LJInvocationCenter
274 |
275 | - (instancetype)init
276 | {
277 | self = [super init];
278 | if (self)
279 | {
280 | self.allItem = [[NSMutableDictionary alloc] init];
281 | }
282 | return self;
283 | }
284 | - (void)addInvocationWithKey:(NSString *)key
285 | target:(__unsafe_unretained id)target
286 | rule:(LJInvocationCenterItemRule *)rule
287 | {
288 | if (!key.length || !target || !rule || !rule.selector || !rule.returnTypeName.length )
289 | {
290 | return;
291 | }
292 |
293 |
294 |
295 |
296 | // 一共分三种情况
297 | LJInvocationCenterItem *item = self.allItem[key];
298 |
299 | // 1.直接添加
300 | if (!item)
301 | {
302 | item = [[LJInvocationCenterItem alloc] initWithKey:key target:target];
303 | [item addRule:rule];
304 | self.allItem[key] = item;
305 | }
306 | // 2.相同target
307 | else if (item.target == target)
308 | {
309 | for (LJInvocationCenterItemRule *registedRule in item.rules)
310 | {
311 | // 和已有的rule冲突失败
312 | if (registedRule.selector == rule.selector)
313 | {
314 | return;
315 | }
316 | }
317 | [item addRule:rule];
318 | }
319 | else
320 | {
321 | NSLog(@"页面 %@ 与 页面 %@ 同时注册了 key:\"%@\"",item.target,target,key);
322 | assert(0);
323 | }
324 | }
325 |
326 | - (NSInvocation*)invocationForTarget:(id)target rule:(LJInvocationCenterItemRule*)rule data:(NSDictionary*)data
327 | {
328 | NSMutableArray *paramValues = [[NSMutableArray alloc] init];
329 | for (LJInvocationCenterItemParam *param in rule.paramas)
330 | {
331 | id value = [data valueForKey:param.name];
332 | if (!value && param.isRequire)
333 | {
334 | return nil;
335 | }
336 | [paramValues addObject:value?:[NSNull null]];
337 | }
338 |
339 | Class clazz = object_getClass(target);
340 | Method method = class_getInstanceMethod(clazz, rule.selector);
341 |
342 | NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:method_getTypeEncoding(method)];
343 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
344 | invocation.target = target;
345 | invocation.selector = rule.selector;
346 |
347 |
348 |
349 | NSMutableArray *allInvokeValue = nil;
350 | for (NSInteger idx = 0 ; idx < paramValues.count ; idx ++)
351 | {
352 | id obj = paramValues[idx];
353 | if (obj == [NSNull null])
354 | {
355 | continue;
356 | }
357 | LJInvocationCenterItemParam *param = rule.paramas[idx];
358 |
359 | LJRouterConvertInvokeValue *invokeValue = [self.convertManager invokeValueWithJson:obj param:param];
360 |
361 | if (invokeValue)
362 | {
363 | [invocation setArgument:invokeValue.result atIndex:idx+2];
364 | if (!allInvokeValue)
365 | {
366 | allInvokeValue = [[NSMutableArray alloc] init];
367 | static char someKey;
368 | objc_setAssociatedObject(invocation, &someKey , allInvokeValue, OBJC_ASSOCIATION_RETAIN);
369 | }
370 | [allInvokeValue addObject:invokeValue];
371 | }
372 | else
373 | {
374 | [invocation setArgument:(void*)&obj atIndex:idx + 2];
375 | }
376 | }
377 |
378 | return invocation;
379 | }
380 |
381 | - (void)runInvocation:(NSInvocation*)invocation
382 | {
383 | [invocation invoke];
384 | }
385 |
386 | - (NSInvocation*)invocationWithKey:(NSString *)key
387 | data:(NSDictionary *)data
388 | outItem:(LJInvocationCenterItem *__autoreleasing *)outItem
389 | outRule:(LJInvocationCenterItemRule *__autoreleasing *)outRule
390 | {
391 | LJInvocationCenterItem *item = self.allItem[key];
392 | for (LJInvocationCenterItemRule *rule in item.rules)
393 | {
394 | NSInvocation *invocation = [self invocationForTarget:item.target rule:rule data:data];
395 | if (invocation)
396 | {
397 | if (outItem)
398 | {
399 | *outItem = item;
400 | }
401 | if (outRule)
402 | {
403 | *outRule = rule;
404 | }
405 | return invocation;
406 | }
407 | }
408 | return nil;
409 | }
410 |
411 | - (LJInvocationCenterItem*)getInvocationCenterItemByKey:(NSString*)key
412 | {
413 | return [self.allItem valueForKey:key];
414 | }
415 |
416 | @end
417 |
--------------------------------------------------------------------------------
/LJRouter/Core/LJRouter.h:
--------------------------------------------------------------------------------
1 | //
2 | // LJRouter.h
3 | // invocation
4 | //
5 | // Created by fover0 on 2017/5/28.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | #import
10 | #import "LJInvocationCenter.h"
11 | #import "LJRouterConvertManager.h"
12 |
13 | typedef NS_ENUM(NSUInteger, LJRouterCheckPolicy) {
14 | LJRouterCheckPolicyAssert = 0, // default
15 | LJRouterCheckPolicyConsole = 1,
16 | LJRouterCheckPolicyAlert = 2,
17 | };
18 |
19 | typedef void(^LJRouterCallbackBlock)(NSString* mess,BOOL complete);
20 |
21 | @interface LJRouter : NSObject
22 |
23 | @property (nonatomic, readonly) LJRouterConvertManager *convertManager;
24 |
25 | // 初始化
26 | + (instancetype)sharedInstance;
27 | - (instancetype)init __deprecated;
28 |
29 | // router
30 | - (BOOL)canRouterKey:(NSString*)key data:(NSDictionary*)data;
31 | - (BOOL)routerKey:(NSString*)key
32 | data:(NSDictionary*)data
33 | sender:(UIResponder*)sender
34 | pageBlock:(void(^)(__kindof UIViewController* viewController))pageBlock
35 | callbackBlock:(void(^)(NSString* key,NSString *value,NSString* data,BOOL complete))callbackBlock
36 | canNotRouterBlock:(void(^)(void))canNotRouterBlock;
37 |
38 | - (void)openViewController:(UIViewController*)vc withSender:(id)sender;
39 |
40 | @end
41 |
42 | @interface LJRouterSenderContext : NSObject
43 |
44 | // 原始sender
45 | @property (nonatomic, readonly) UIResponder *originSender;
46 |
47 | // 以下函数 会按照originSender本身以及nextResponder依次寻找命中该类型的对象
48 | @property (nonatomic, readonly) UIView *contextView;
49 | @property (nonatomic, readonly) UIViewController *contextViewController;
50 | @property (nonatomic, readonly) UIWindow *contextWindow;
51 | @property (nonatomic, readonly) id contextAppDelegate;
52 | @property (nonatomic, readonly) UIApplication *contextAppliaction;
53 |
54 | @end
55 |
56 |
57 | @interface LJRouter(config)
58 |
59 | // 默认为nil , nil与@[]时检查所有模块
60 | @property (nonatomic, retain) NSArray *checkPolicyModules;
61 | @property (nonatomic, assign) LJRouterCheckPolicy checkPolicy;
62 |
63 | @property (nonatomic, copy) void(^openControllerBlock)(UIViewController*vc,id sender) __deprecated_msg("请使用openControllerWithContextBlock");
64 | @property (nonatomic, copy) void(^openControllerWithContextBlock)(UIViewController*vc, LJRouterSenderContext *senderContext);
65 |
66 | @end
67 |
68 | @interface UIViewController(LJRouter)
69 |
70 | // 属性是通过实例调用 如果该页面通过路由产生 则会返回该次路由所使用的key
71 | // 请不要直接设置该属性
72 | @property (nonatomic, copy) NSString *ljRouterKey;
73 | @end
74 |
75 |
76 |
77 | #import "LJRouterPrivate.h"
78 |
--------------------------------------------------------------------------------
/LJRouter/Core/LJRouter.m:
--------------------------------------------------------------------------------
1 | //
2 | // LJRouter.m
3 | // invocation
4 | //
5 | // Created by fover0 on 2017/5/28.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 | #import
13 | #import
14 |
15 | #ifndef __LP64__
16 | #define section_ section
17 | #define mach_header_ mach_header
18 | #else
19 | #define section_ section_64
20 | #define mach_header_ mach_header_64
21 | #endif
22 |
23 | #import "LJRouter.h"
24 | #import "LJInvocationCenter.h"
25 |
26 |
27 | #define LJRouterCallbackBlockName @"LJRouterCallbackBlock"
28 |
29 | @implementation UIViewController(LJRouter)
30 |
31 | static char ljRouterKeyKey;
32 | - (void)setLjRouterKey:(NSString *)ljRouterKey
33 | {
34 | objc_setAssociatedObject(self, &ljRouterKeyKey, [ljRouterKey copy], OBJC_ASSOCIATION_RETAIN);
35 | }
36 |
37 | - (NSString*)ljRouterKey
38 | {
39 | return objc_getAssociatedObject(self, &ljRouterKeyKey);
40 | }
41 |
42 | @end
43 |
44 | @interface LJRouterSenderContext()
45 |
46 | // 原始sender
47 | @property (nonatomic, retain) UIResponder *originSender;
48 |
49 | // 以下函数 会按照originSender本身以及nextResponder依次寻找命中该类型的对象
50 | @property (nonatomic, retain) UIView *contextView;
51 | @property (nonatomic, retain) UIViewController *contextViewController;
52 | @property (nonatomic, retain) UIWindow *contextWindow;
53 | @property (nonatomic, retain) id contextAppDelegate;
54 | @property (nonatomic, retain) UIApplication *contextAppliaction;
55 |
56 | @end
57 |
58 | @implementation LJRouterSenderContext
59 |
60 | - (instancetype)initWithSender:(UIResponder*)sender
61 | {
62 | self = [super init];
63 | if (self)
64 | {
65 | self.originSender = sender;
66 | [self loadResponderWithSender:sender];
67 | }
68 | return self;
69 | }
70 |
71 | - (void)loadResponderWithSender:(UIResponder*)sender
72 | {
73 | UIResponder *r = sender;
74 | while (r) {
75 | if ([r isKindOfClass:[UIView class]])
76 | {
77 | if (!_contextView)
78 | {
79 | _contextView = (UIView*)r;
80 | _contextWindow = _contextView.window;
81 | }
82 | }
83 | else if ([r isKindOfClass:[UIViewController class]])
84 | {
85 | if (!_contextViewController)
86 | {
87 | _contextViewController = (UIViewController*)r;
88 | }
89 | }
90 | else if ([r isKindOfClass:[UIApplication class]])
91 | {
92 | if (!_contextAppliaction)
93 | {
94 | _contextAppliaction = (UIApplication*)r;
95 | _contextAppDelegate = _contextAppliaction.delegate;
96 | }
97 | }
98 |
99 | r = r.nextResponder;
100 | }
101 | }
102 |
103 | @end
104 |
105 |
106 | @interface LJRouter ()
107 | {
108 | void(^_openControllerBlock)(UIViewController*vc,id sender);
109 | void(^_openControllerWithSenderBlock)(UIViewController*vc,LJRouterSenderContext *senderContext);
110 | LJRouterCheckPolicy _checkPolicy;
111 | NSArray *_checkPolicyModules;
112 | }
113 |
114 | @property (nonatomic, retain) LJInvocationCenter *pageInvocationCenter;
115 | @property (nonatomic, retain) LJInvocationCenter *actionInvocationCenter;
116 | @end
117 |
118 | static NSMutableDictionary *allKeyMethods = nil;
119 |
120 | @implementation LJRouter
121 |
122 | @synthesize convertManager = _convertManager;
123 |
124 | + (instancetype)sharedInstance
125 | {
126 | static id instance = nil;
127 | static dispatch_once_t onceToken;
128 | dispatch_once(&onceToken, ^{
129 | instance = [[self alloc] initPrivate];
130 | });
131 | return instance;
132 | }
133 |
134 | - (void)loadAllPageProperty
135 | {
136 | LJRouterConvertManager *convertManager = [[LJRouterConvertManager alloc] init];
137 | _convertManager = convertManager;
138 |
139 | LJInvocationCenter *pageCenter = [[LJInvocationCenter alloc] init];
140 | _pageInvocationCenter = pageCenter;
141 | _pageInvocationCenter.convertManager = convertManager;
142 |
143 | LJInvocationCenter *actionCenter = [[LJInvocationCenter alloc] init];
144 | _actionInvocationCenter = actionCenter;
145 | _actionInvocationCenter.convertManager = convertManager;
146 |
147 | uint32_t count = _dyld_image_count();
148 | for (uint32_t i = 0 ; i < count ; i++)
149 | {
150 | const struct mach_header_* header = (void*)_dyld_get_image_header(i);
151 | unsigned long size = 0;
152 | // 注册所有的vc
153 | uint8_t *data = getsectiondata(header, "__DATA", "__LJRouter",&size);
154 | if (data && size > 0)
155 | {
156 | struct LJRouterRegister *items = (struct LJRouterRegister*)data;
157 | uint32_t count = (uint32_t)(size / sizeof(struct LJRouterRegister));
158 | for (uint32_t i = 0 ; i < count ; i ++)
159 | {
160 | NSMutableString *methodKeyTypeVarName = [[NSMutableString alloc] initWithString:items[i].returnTypeName];
161 | NSMutableArray *params = nil;
162 | if (items[i].paramscount)
163 | {
164 | params = [[NSMutableArray alloc] init];
165 | for (uint32_t j = 0 ; j < items[i].paramscount ; j ++)
166 | {
167 | BOOL isRequire = items[i].params[j].isRequire;
168 | if ([items[i].params[j].typeName isEqualToString:LJRouterCallbackBlockName])
169 | {
170 | isRequire = NO;
171 | }
172 |
173 | LJInvocationCenterItemParam *param =
174 | [[LJInvocationCenterItemParam alloc] initWithName:items[i].params[j].name.lowercaseString
175 | typeName:items[i].params[j].typeName
176 | typeEncoding:[NSString stringWithFormat:@"%s",items[i].params[j].typeEncoding]
177 | isRequire:isRequire
178 | info:nil];
179 |
180 | [params addObject:param];
181 |
182 | [methodKeyTypeVarName appendString:items[i].params[j].typeName];
183 | [methodKeyTypeVarName appendString:items[i].params[j].name];
184 | }
185 | }
186 |
187 | NSMutableArray *methodNames = allKeyMethods[items[i].key.lowercaseString];
188 | if (!methodNames)
189 | {
190 | methodNames = [[NSMutableArray alloc] init];
191 | allKeyMethods[items[i].key.lowercaseString] = methodNames;
192 | }
193 | [methodNames addObject:[methodKeyTypeVarName stringByReplacingOccurrencesOfString:@" " withString:@""]];
194 |
195 | LJInvocationCenter *center = items[i].isAction ? actionCenter : pageCenter;
196 |
197 | NSString *functionName = [[NSString alloc] initWithUTF8String:items[i].objcFunctionName];
198 | NSRange range = [functionName rangeOfString:@" "];
199 | NSString *className = [functionName substringWithRange:NSMakeRange(2, range.location - 2)];
200 | range = [className rangeOfString:@"("];
201 | if (range.length)
202 | {
203 | className = [className substringToIndex:range.location];
204 | }
205 |
206 | LJInvocationCenterItemRule *rule =
207 | [[LJInvocationCenterItemRule alloc] initWithSelector:NSSelectorFromString(items[i].selName)
208 | returnTypeName:items[i].returnTypeName
209 | returnTypeEncoding:[NSString stringWithUTF8String:items[i].returnTypeEncoding]
210 | params:params];
211 |
212 | [center addInvocationWithKey:items[i].key.lowercaseString
213 | target:NSClassFromString(className)
214 | rule:rule];
215 | }
216 | break;
217 | }
218 | }
219 | }
220 |
221 | BOOL LJRouterCheckMethodType(NSString *key,
222 | NSString *returnTypeName,
223 | struct LJRouterRegisterParam* originParams,
224 | uint32_t paramsCount,
225 | NSString **errorMessage)
226 | {
227 | NSMutableString *methodName = [[NSMutableString alloc] initWithString:returnTypeName];
228 | for (uint32_t i = 0 ; i < paramsCount ; i++)
229 | {
230 | struct LJRouterRegisterParam *param = originParams + i;
231 | [methodName appendString:param->typeName];
232 | [methodName appendString:param->name];
233 | }
234 | NSString *methodNameComp = [methodName stringByReplacingOccurrencesOfString:@" " withString:@""];
235 |
236 | NSArray *methodNamesArray = [allKeyMethods valueForKey:key.lowercaseString];
237 | for (NSString *name in methodNamesArray)
238 | {
239 | if ([name isEqualToString:methodNameComp])
240 | {
241 | return YES;
242 | }
243 | }
244 | if (errorMessage)
245 | {
246 | *errorMessage = @"参数类型或变量名不匹配,请检查";
247 | }
248 |
249 | return NO;
250 |
251 | }
252 |
253 | - (BOOL)checkInModules:(NSString*)filePath
254 | {
255 | if (self.checkPolicyModules.count == 0)
256 | {
257 | return YES;
258 | }
259 |
260 | NSArray *paths = [filePath componentsSeparatedByString:@"/"];
261 | for (NSString *path in paths)
262 | {
263 | for (NSString *module in self.checkPolicyModules)
264 | {
265 | if ([path isEqualToString:module])
266 | {
267 | return YES;
268 | }
269 | }
270 | }
271 | return NO;
272 | }
273 |
274 | - (void)checkAllMethodTypeName
275 | {
276 | uint32_t count = _dyld_image_count();
277 | for (uint32_t i = 0 ; i < count ; i++)
278 | {
279 | const struct mach_header_* header = (void*)_dyld_get_image_header(i);
280 | unsigned long size = 0;
281 | // 检查所有的函数类型
282 | uint8_t *data = getsectiondata(header, "__DATA", "__LJRouterUseINF",&size);
283 | if (data && size > 0)
284 | {
285 | struct LJRouterUseInfo* infos = (void*)data;
286 | uint32_t count = (uint32_t)(size / sizeof(struct LJRouterUseInfo));
287 | NSMutableString *alertMessage = nil;
288 | for (uint32_t i = 0 ; i < count ; i ++)
289 | {
290 | struct LJRouterUseInfo *info = infos + i;
291 | NSString *filePath = [NSString stringWithUTF8String:info->filePath];
292 | if (![self checkInModules:filePath])
293 | {
294 | continue;
295 | }
296 |
297 | NSString *message = nil;
298 | BOOL check =
299 | LJRouterCheckMethodType(info->key,
300 | info->returnTypeName,
301 | info->params,
302 | info->paramCount,
303 | &message);
304 | if (!check)
305 | {
306 | if (self.checkPolicy == LJRouterCheckPolicyAssert)
307 | {
308 | void** addr = (void**)info->assertBlock;
309 | void(^block)(NSString*) = (__bridge id)*addr;
310 | block(message);
311 | }
312 | else if (self.checkPolicy == LJRouterCheckPolicyConsole)
313 | {
314 | NSLog(@"文件 %s 行号 %llu",info->filePath,info->lineNumber);
315 | }
316 | else if (self.checkPolicy == LJRouterCheckPolicyAlert)
317 | {
318 | if (!alertMessage)
319 | {
320 | alertMessage = [[NSMutableString alloc] init];
321 | }
322 |
323 | NSString *file = [[NSString alloc] initWithUTF8String:info->filePath];
324 | NSArray *comp = [file componentsSeparatedByString:@"/"];
325 |
326 | [alertMessage appendFormat:@"%@:%llu %@\n",comp.lastObject,info->lineNumber,info->key];
327 | }
328 | }
329 | }
330 | if (alertMessage.length)
331 | {
332 | UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"校验错误" message:alertMessage delegate:nil cancelButtonTitle:@"知道了" otherButtonTitles:nil];
333 | [alertView show];
334 | }
335 | }
336 | }
337 | }
338 |
339 | - (instancetype)initPrivate
340 | {
341 | self = [super init];
342 | if (self)
343 | {
344 | _openControllerBlock = nil;
345 | allKeyMethods = [[NSMutableDictionary alloc] init];
346 | _checkPolicy = LJRouterCheckPolicyAssert;
347 | _checkPolicyModules = nil;
348 | }
349 | return self;
350 | }
351 |
352 | - (void)loadAndCheck
353 | {
354 | static dispatch_once_t onceToken;
355 | dispatch_once(&onceToken, ^{
356 | [self loadAllPageProperty];
357 | [self checkAllMethodTypeName];
358 | });
359 | }
360 |
361 | - (LJInvocationCenter*)actionInvocationCenter
362 | {
363 | [self loadAndCheck];
364 | return _actionInvocationCenter;
365 | }
366 |
367 | - (LJInvocationCenter*)pageInvocationCenter
368 | {
369 | [self loadAndCheck];
370 | return _pageInvocationCenter;
371 | }
372 |
373 | - (LJRouterConvertManager*)convertManager
374 | {
375 | [self loadAndCheck];
376 | return _convertManager;
377 | }
378 |
379 | - (instancetype)init
380 | {
381 | return [[self class] sharedInstance];
382 | }
383 |
384 | - (BOOL)canRouterKey:(NSString *)key data:(NSDictionary *)data
385 | {
386 | NSInvocation *pageInvocation =
387 | [self.pageInvocationCenter invocationWithKey:key.lowercaseString
388 | data:data
389 | outItem:nil
390 | outRule:nil];
391 | if (pageInvocation)
392 | {
393 | return YES;
394 | }
395 |
396 | NSInvocation *actionInvocation =
397 | [self.actionInvocationCenter invocationWithKey:key.lowercaseString
398 | data:data
399 | outItem:nil
400 | outRule:nil];
401 | if (actionInvocation)
402 | {
403 | return YES;
404 | }
405 | else
406 | {
407 | return NO;
408 | }
409 | }
410 |
411 | - (BOOL)routerKey:(NSString *)key
412 | data:(NSDictionary *)data
413 | sender:(UIResponder *)sender
414 | pageBlock:(void (^)(__kindof UIViewController *))pageBlock
415 | callbackBlock:(void (^)(NSString *, NSString *, NSString *, BOOL))callbackBlock
416 | canNotRouterBlock:(void (^)(void))canNotRouterBlock
417 | {
418 | NSInvocation *invocation = [self.pageInvocationCenter invocationWithKey:key.lowercaseString
419 | data:data
420 | outItem:nil
421 | outRule:nil];
422 | if (invocation)
423 | {
424 | [invocation invoke];
425 | __unsafe_unretained UIViewController *unsafeVC = nil;
426 | [invocation getReturnValue:&unsafeVC];
427 | UIViewController *ret = unsafeVC;
428 | if (pageBlock)
429 | {
430 | pageBlock(ret);
431 | }
432 | return YES;
433 | }
434 |
435 | LJInvocationCenterItem *outItem = nil;
436 | LJInvocationCenterItemRule *outRule = nil;
437 |
438 | NSMutableDictionary *actionData = [[NSMutableDictionary alloc] initWithDictionary:data];
439 | actionData[@"sender"] = sender;
440 | invocation = [self.actionInvocationCenter invocationWithKey:key.lowercaseString
441 | data:actionData
442 | outItem:&outItem
443 | outRule:&outRule];
444 |
445 | if (invocation)
446 | {
447 | __block BOOL hasCallbackBlock = NO;
448 | [outRule.paramas enumerateObjectsUsingBlock:^(LJInvocationCenterItemParam * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
449 |
450 | NSString *senderClass = NSStringFromClass([LJRouterSenderContext class]);
451 |
452 | if([obj.typeName hasPrefix:senderClass]
453 | && [obj.name.lowercaseString isEqualToString:@"sender"])
454 | {
455 | __unsafe_unretained id originSender = nil;
456 | [invocation getArgument:&originSender atIndex:idx+2];
457 | LJRouterSenderContext *senderContext = [[LJRouterSenderContext alloc] initWithSender:originSender];
458 | [invocation setArgument:&senderContext atIndex:idx+2];
459 | [invocation retainArguments];
460 | }
461 | else if ([obj.typeName isEqualToString:LJRouterCallbackBlockName])
462 | {
463 | hasCallbackBlock = YES;
464 | __unsafe_unretained id unsafe_data = nil;
465 | [invocation getArgument:&unsafe_data atIndex:idx+2];
466 | id data = unsafe_data;
467 |
468 | void (^_callbackBlock)(NSString *,NSString *,NSString *,BOOL) = [callbackBlock copy];
469 |
470 | void(^block)(NSString*,BOOL) = ^(NSString *blockData,BOOL complete) {
471 | if (_callbackBlock)
472 | {
473 | _callbackBlock(obj.name,data,blockData,complete);
474 | }
475 | };
476 | block = [block copy];
477 | [invocation setArgument:&block atIndex:idx+2];
478 | [invocation retainArguments];
479 | }
480 | }];
481 | [invocation invoke];
482 |
483 |
484 | if (!hasCallbackBlock && callbackBlock)
485 | {
486 | callbackBlock(nil,nil,nil,YES);
487 | }
488 | return YES;
489 | }
490 |
491 | if (canNotRouterBlock)
492 | {
493 | canNotRouterBlock();
494 | }
495 | return NO;
496 | }
497 |
498 | - (LJInvocationCenterItem*)invocationItemForKey:(NSString*)key
499 | {
500 | LJInvocationCenterItem *item = [self.pageInvocationCenter getInvocationCenterItemByKey:key.lowercaseString];
501 | if (item)
502 | {
503 | return item;
504 | }
505 | else
506 | {
507 | return [self.actionInvocationCenter getInvocationCenterItemByKey:key.lowercaseString];
508 | }
509 | }
510 |
511 | - (void)openViewController:(UIViewController *)vc withSender:(id)sender
512 | {
513 | if (!vc)
514 | {
515 | return;
516 | }
517 | #pragma clang diagnostic push
518 | #pragma clang diagnostic ignored "-Wdeprecated-declarations"
519 | #pragma clang diagnostic ignored "-Wundeclared-selector"
520 | if (self.openControllerBlock)
521 | {
522 | self.openControllerBlock(vc,sender);
523 | }
524 |
525 | else if (self.openControllerWithContextBlock)
526 | {
527 | self.openControllerWithContextBlock(vc, [[LJRouterSenderContext alloc] initWithSender:sender]);
528 | }
529 | else if ([vc respondsToSelector:@selector(LJNavigationOpenedByViewController:)])
530 | {
531 | LJRouterSenderContext *senderContext = [[LJRouterSenderContext alloc] initWithSender:sender];
532 | if (senderContext.contextViewController)
533 | {
534 | [vc performSelector:@selector(LJNavigationOpenedByViewController:)
535 | withObject: senderContext.contextViewController];
536 | }
537 | else
538 | {
539 | [UIViewController performSelector:@selector(LJNavigationOpenViewController:) withObject:vc];
540 | }
541 | }
542 | #pragma clang diagnostic pop
543 | else
544 | {
545 | NSLog(@"请配置 LJRouter 的 openControllerBlock 属性进行页面打开");
546 | }
547 | }
548 |
549 | @end
550 |
551 | @implementation LJRouter(config)
552 |
553 | - (void)setCheckPolicy:(LJRouterCheckPolicy)checkPolicy
554 | {
555 | _checkPolicy = checkPolicy;
556 | }
557 |
558 | - (LJRouterCheckPolicy)checkPolicy
559 | {
560 | return _checkPolicy;
561 | }
562 |
563 | - (void)setCheckPolicyModules:(NSArray *)checkPolicyModules
564 | {
565 | _checkPolicyModules = checkPolicyModules;
566 | }
567 |
568 | - (NSArray*)checkPolicyModules
569 | {
570 | return _checkPolicyModules;
571 | }
572 |
573 | - (void)setOpenControllerBlock:(void (^)(UIViewController *, id))openControllerBlock
574 | {
575 | _openControllerBlock = [openControllerBlock copy];
576 | }
577 |
578 | - (void (^)(UIViewController *, id))openControllerBlock
579 | {
580 | return _openControllerBlock;
581 | }
582 |
583 | - (void)setOpenControllerWithContextBlock:(void (^)(UIViewController *, LJRouterSenderContext *))openControllerWithContextBlock
584 | {
585 | _openControllerWithSenderBlock = openControllerWithContextBlock;
586 | }
587 |
588 | - (void(^)(UIViewController*,LJRouterSenderContext*))openControllerWithContextBlock
589 | {
590 | return _openControllerWithSenderBlock;
591 | }
592 |
593 | @end
594 |
595 | Class LJRouterGetClassForKey(NSString* key)
596 | {
597 | LJRouter *router = [LJRouter sharedInstance];
598 | Class clazz = [router.pageInvocationCenter getInvocationCenterItemByKey:key.lowercaseString].target;
599 | if (clazz)
600 | {
601 | return clazz;
602 | }
603 | return [router.actionInvocationCenter getInvocationCenterItemByKey:key.lowercaseString].target;
604 | }
605 |
606 | NSInvocation* LJRouterGetInvocation(struct LJRouterInvocationStruct* invocations,uint32_t length)
607 | {
608 | LJRouterConvertManager *manager = [LJRouter sharedInstance].convertManager;
609 | NSMutableDictionary *data = nil;
610 | for (uint32_t i = 0 ; i < length ; i ++)
611 | {
612 | struct LJRouterInvocationStruct* invocation = invocations + i;
613 | LJInvocationCenterItemParam *param = [[LJInvocationCenterItemParam alloc] initWithName:invocation->name
614 | typeName:invocation->typeName
615 | typeEncoding:[NSString stringWithUTF8String:invocation->typeEncoding]
616 | isRequire:NO
617 | info:nil];
618 | id jsonValue = [manager jsonValueWithInvokeValue:invocation->value param:param];
619 | if (!jsonValue)
620 | {
621 | return nil;
622 | }
623 | if (!data)
624 | {
625 | data = [[NSMutableDictionary alloc] init];
626 | }
627 | data[invocation->name] = jsonValue;
628 | }
629 |
630 | return nil;
631 | }
632 |
--------------------------------------------------------------------------------
/LJRouter/Core/LJRouterConvertManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // LJRouterConvertManager.h
3 | // LJRouter
4 | //
5 | // Created by fover0 on 2017/11/28.
6 | //
7 |
8 | #import
9 |
10 | @class LJInvocationCenterItemParam;
11 |
12 | // 类型转化结果
13 | @interface LJRouterConvertInvokeValue : NSObject
14 |
15 | @property (nonatomic, readonly) void* result;
16 |
17 | + (instancetype)valueWithCType:(void*)result freeWhenDone:(BOOL)free;
18 | + (instancetype)valueWithRetainObj:(id)result;
19 | + (instancetype)valueError;
20 |
21 | @end
22 |
23 |
24 | @interface LJRouterConvertManager : NSObject
25 |
26 | - (LJRouterConvertInvokeValue*)invokeValueWithJson:(id)jsonValue param:(LJInvocationCenterItemParam*)param;
27 | - (id)jsonValueWithInvokeValue:(void*)jsonValue param:(LJInvocationCenterItemParam*)param;
28 |
29 | - (void)addCovertInvokeValueBlock:(LJRouterConvertInvokeValue*(^)(LJRouterConvertManager *manager,
30 | id value,
31 | LJInvocationCenterItemParam *targetParam))invokeValue;
32 |
33 |
34 | - (void)addConvertJsonValueBlock:(id(^)(LJRouterConvertManager *manager,
35 | void* value,
36 | LJInvocationCenterItemParam *valueParam))jsonValueBlock;
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/LJRouter/Core/LJRouterConvertManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // LJRouterConvertManager.m
3 | // LJRouter
4 | //
5 | // Created by fover0 on 2017/11/28.
6 | //
7 |
8 | #import "LJRouterConvertManager.h"
9 | #import "LJInvocationCenter.h"
10 | #import "LJRouter.h"
11 |
12 | @interface LJRouterConvertInvokeValue()
13 | {
14 | @public
15 | __strong id _resultObj;
16 | void* _resultPointer;
17 | BOOL _freeWhenDone;
18 | }
19 |
20 | @end
21 |
22 | @implementation LJRouterConvertInvokeValue
23 |
24 | + (instancetype)valueWithRetainObj:(id)result
25 | {
26 | LJRouterConvertInvokeValue *ret = [[self alloc] init];
27 | ret->_resultObj = result;
28 | return ret;
29 | }
30 |
31 | + (instancetype)valueWithCType:(void *)result freeWhenDone:(BOOL)free
32 | {
33 | LJRouterConvertInvokeValue *ret = [[self alloc] init];
34 | ret->_resultPointer = result;
35 | ret->_freeWhenDone = free;
36 | return ret;
37 | }
38 |
39 | - (void*)result
40 | {
41 | if (_resultObj)
42 | {
43 | return &_resultObj;
44 | }
45 | else
46 | {
47 | return _resultPointer;
48 | }
49 | }
50 |
51 | + (instancetype)valueError
52 | {
53 | static id error = nil;
54 | static dispatch_once_t onceToken;
55 | dispatch_once(&onceToken, ^{
56 | error = [[self alloc] init];
57 | });
58 | return error;
59 | }
60 |
61 | - (void)dealloc
62 | {
63 | if (self->_freeWhenDone)
64 | {
65 | free(self->_resultPointer);
66 | self->_resultPointer = NULL;
67 | }
68 | }
69 |
70 | @end
71 |
72 | @interface LJRouterConvertManager()
73 | @property (nonatomic, retain) NSMutableArray *invokeValueBlocks;
74 | @property (nonatomic, retain) NSMutableArray *jsonValueBlocks;
75 | @end
76 |
77 | @implementation LJRouterConvertManager
78 |
79 | #define ALL_NUMBER_TYPE(CONVERT_NUMBER) \
80 | CONVERT_NUMBER(signed char ,_C_CHR , charValue) \
81 | CONVERT_NUMBER(unsigned char ,_C_UCHR , unsignedCharValue) \
82 | CONVERT_NUMBER(signed short ,_C_SHT , shortValue) \
83 | CONVERT_NUMBER(unsigned short ,_C_USHT , unsignedShortValue) \
84 | CONVERT_NUMBER(signed int ,_C_INT , intValue) \
85 | CONVERT_NUMBER(unsigned int ,_C_UINT , unsignedIntValue) \
86 | CONVERT_NUMBER(signed long ,_C_LNG , longValue) \
87 | CONVERT_NUMBER(unsigned long ,_C_ULNG , unsignedLongValue) \
88 | CONVERT_NUMBER(signed long long ,_C_LNG_LNG , longLongValue) \
89 | CONVERT_NUMBER(bool ,_C_BOOL , boolValue) \
90 | CONVERT_NUMBER(unsigned long long ,_C_ULNG_LNG, unsignedLongLongValue) \
91 | CONVERT_NUMBER(float ,_C_FLT , floatValue) \
92 | CONVERT_NUMBER(double ,_C_DBL , doubleValue) \
93 |
94 | - (void)regNumberConvert
95 | {
96 | [self addCovertInvokeValueBlock:^LJRouterConvertInvokeValue *(LJRouterConvertManager *manager,
97 | id value,
98 | LJInvocationCenterItemParam *targetParam) {
99 | NSNumber*(^getNumber)(id numberObj) = ^NSNumber*(id numberObj){
100 | if ([numberObj isKindOfClass:[NSString class]])
101 | {
102 | NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
103 | return [f numberFromString:numberObj];
104 | }
105 | else if ([numberObj isKindOfClass:[NSNumber class]])
106 | {
107 | return numberObj;
108 | }
109 | else
110 | {
111 | return @0;
112 | }
113 | };
114 |
115 | const char* type = targetParam.typeEncoding.UTF8String;
116 | switch (type[0]) {
117 | // 处理数字
118 | #define CONVERT_NUMBER(TYPE,TYPENAME,METHODNAME) \
119 | case TYPENAME: \
120 | { \
121 | TYPE c = [getNumber(value) METHODNAME]; \
122 | TYPE *result = (void*)malloc(sizeof(TYPE)); \
123 | *result = c; \
124 | return \
125 | [LJRouterConvertInvokeValue valueWithCType:result freeWhenDone:YES]; \
126 | } \
127 |
128 | ALL_NUMBER_TYPE(CONVERT_NUMBER)
129 | #undef CONVERT_NUMBER
130 | default:
131 | return nil;
132 | }
133 | }];
134 |
135 | [self addConvertJsonValueBlock:^id(LJRouterConvertManager *manager,
136 | void *value,
137 | LJInvocationCenterItemParam *valueParam) {
138 | const char* type = valueParam.typeEncoding.UTF8String;
139 | switch (type[0]) {
140 | #define CONVERT_NUMBER(TYPE,TYPENAME,METHODNAME) \
141 | case TYPENAME: \
142 | { \
143 | TYPE *c = (TYPE*)value; \
144 | return @(*c); \
145 | } \
146 |
147 | ALL_NUMBER_TYPE(CONVERT_NUMBER)
148 | #undef CONVERT_NUMBER
149 | default:
150 | return nil;
151 | }
152 | }];
153 | }
154 |
155 | - (instancetype)init
156 | {
157 | self = [super init];
158 | if (self)
159 | {
160 | self.invokeValueBlocks = [[NSMutableArray alloc] init];
161 | self.jsonValueBlocks = [[NSMutableArray alloc] init];
162 |
163 | [self regNumberConvert];
164 | }
165 | return self;
166 | }
167 |
168 | - (void)addCovertInvokeValueBlock:(LJRouterConvertInvokeValue *(^)(LJRouterConvertManager *,id,LJInvocationCenterItemParam *))invokeValue
169 | {
170 | if (invokeValue)
171 | {
172 | [self.invokeValueBlocks addObject:invokeValue];
173 | }
174 | }
175 | - (void)addConvertJsonValueBlock:(id (^)(LJRouterConvertManager *, void *, LJInvocationCenterItemParam *))jsonValueBlock
176 | {
177 | if (jsonValueBlock)
178 | {
179 | [self.jsonValueBlocks addObject:jsonValueBlock];
180 | }
181 | }
182 |
183 | - (id)jsonValueWithInvokeValue:(void *)jsonValue param:(LJInvocationCenterItemParam *)param
184 | {
185 | for (id (^block)(LJRouterConvertManager *, void *, LJInvocationCenterItemParam *) in self.jsonValueBlocks)
186 | {
187 | id result = block(self,jsonValue,param);
188 | if (result)
189 | {
190 | return result;
191 | }
192 | }
193 | return nil;
194 | }
195 |
196 | - (LJRouterConvertInvokeValue*)invokeValueWithJson:(id)jsonValue param:(LJInvocationCenterItemParam*)param
197 | {
198 | for (LJRouterConvertInvokeValue *(^block)(LJRouterConvertManager *,id,LJInvocationCenterItemParam *) in self.invokeValueBlocks)
199 | {
200 | LJRouterConvertInvokeValue * value = block(self,jsonValue,param);
201 | if (value)
202 | {
203 | if (value == [LJRouterConvertInvokeValue valueError])
204 | {
205 | return nil;
206 | }
207 | return value;
208 | }
209 | }
210 | return nil;
211 | }
212 |
213 | @end
214 |
215 |
216 |
--------------------------------------------------------------------------------
/LJRouter/Core/LJUrlRouter.h:
--------------------------------------------------------------------------------
1 | //
2 | // LJUrlRouter.h
3 | // invocation
4 | //
5 | // Created by fover0 on 2017/6/6.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | #import "LJRouter.h"
10 |
11 |
12 |
13 | @interface LJRouter(LJUrlRouter)
14 |
15 | - (BOOL)canOpenUrlString:(NSString*)url;
16 | - (BOOL)routerUrlString:(NSString*)url
17 | sender:(UIResponder*)sender
18 | pageBlock:(void(^)(__kindof UIViewController* viewController))pageBlock
19 | callbackBlock:(void(^)(NSString* key,NSString *value,NSString* data,BOOL complete))callbackBlock
20 | canNotRouterBlock:(void(^)(void))canNotRouterBlock;
21 | @end
22 |
23 | @interface LJRouter(LJUrlRouterConfig)
24 |
25 | @property (nonatomic, copy) UIViewController *(^createWebviewBlock)(NSString* url);
26 | @property (nonatomic, copy) NSURL *(^urlProcessorBlock)(NSURL* url);
27 |
28 | @end
29 |
30 | @interface UIViewController(LJUrlRouter)
31 |
32 | + (void)LJSetWebViewControllerBlock:(__kindof UIViewController *(^)(NSString* url))block __deprecated;
33 | - (BOOL)LJOpenUrlString:(NSString*)url;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/LJRouter/Core/LJUrlRouter.m:
--------------------------------------------------------------------------------
1 | //
2 | // LJUrlRouter.m
3 | // invocation
4 | //
5 | // Created by fover0 on 2017/6/6.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | #import "LJUrlRouter.h"
10 |
11 | @implementation LJRouter(LJUrlRouterConfig)
12 |
13 | static char LJUrlRouter_urlProcessorBlock_Key;
14 | - (void)setUrlProcessorBlock:(NSURL *(^)(NSURL *))urlProcessorBlock
15 | {
16 | objc_setAssociatedObject(self, &LJUrlRouter_urlProcessorBlock_Key, [urlProcessorBlock copy], OBJC_ASSOCIATION_RETAIN);
17 | }
18 | - (NSURL *(^)(NSURL *))urlProcessorBlock
19 | {
20 | return objc_getAssociatedObject(self, &LJUrlRouter_urlProcessorBlock_Key);
21 | }
22 |
23 | static char LJUrlRouter_createWebviewBlock_Key;
24 | - (void)setCreateWebviewBlock:(UIViewController *(^)(NSString *))createWebviewBlock
25 | {
26 | objc_setAssociatedObject(self, &LJUrlRouter_createWebviewBlock_Key, [createWebviewBlock copy], OBJC_ASSOCIATION_RETAIN);
27 | }
28 | - (UIViewController *(^)(NSString *))createWebviewBlock
29 | {
30 | return objc_getAssociatedObject(self, &LJUrlRouter_createWebviewBlock_Key);
31 | }
32 |
33 | @end
34 |
35 |
36 | @implementation UIViewController(LJUrlRouter)
37 |
38 | + (void)LJSetWebViewControllerBlock:(__kindof UIViewController *(^)(NSString *))block
39 | {
40 | LJRouter.sharedInstance.createWebviewBlock = block;
41 | }
42 |
43 |
44 | - (BOOL)LJOpenUrlString:(NSString *)url
45 | {
46 | if (url.length == 0)
47 | {
48 | return NO;
49 | }
50 |
51 | BOOL canRout =
52 | [[LJRouter sharedInstance] routerUrlString:url
53 | sender:self
54 | pageBlock:^(__kindof UIViewController *viewController) {
55 | [[LJRouter sharedInstance] openViewController:viewController withSender:self];
56 | }
57 | callbackBlock:nil
58 | canNotRouterBlock:nil];
59 | if (!canRout)
60 | {
61 | UIViewController *(^webviewBlock)(NSString *) = [LJRouter sharedInstance].createWebviewBlock;
62 |
63 | UIViewController *webVC = webviewBlock ? webviewBlock(url) : nil;
64 | if (webVC)
65 | {
66 | canRout = YES;
67 | [[LJRouter sharedInstance] openViewController:webVC withSender:self];
68 | }
69 | }
70 | return canRout;
71 | }
72 |
73 | @end
74 |
75 |
76 |
77 | static NSString *const uq_URLReservedChars = @"=,!$&'()*+;@?\r\n\"<>#\t :/";
78 | static NSString *const kQuerySeparator = @"&";
79 | static NSString *const kQueryDivider = @"=";
80 | static NSString *const kQueryBegin = @"?";
81 | static NSString *const kFragmentBegin = @"#";
82 |
83 | @implementation LJRouter(LJUrlRouter)
84 |
85 | - (NSDictionary*)uq_URLQueryDictionary:(NSString*)string {
86 | NSMutableDictionary *mute = @{}.mutableCopy;
87 | for (NSString *query in [string componentsSeparatedByString:kQuerySeparator]) {
88 | NSArray *components = [query componentsSeparatedByString:kQueryDivider];
89 | if (components.count == 0) {
90 | continue;
91 | }
92 | NSString *key = [components[0] stringByRemovingPercentEncoding];
93 | id value = nil;
94 | if (components.count == 1) {
95 | // key with no value
96 | value = [NSNull null];
97 | }
98 | if (components.count == 2) {
99 | value = [components[1] stringByRemovingPercentEncoding];
100 | // cover case where there is a separator, but no actual value
101 | value = [value length] ? value : [NSNull null];
102 | }
103 | if (components.count > 2) {
104 | // invalid - ignore this pair. is this best, though?
105 | continue;
106 | }
107 | mute[key.lowercaseString] = value ?: [NSNull null];
108 | }
109 | return mute.count ? mute.copy : nil;
110 | }
111 |
112 | - (void)decodeUrlString:(NSString*)urlString
113 | outkey:(NSString**)outKey
114 | outData:(NSDictionary**)outData
115 | {
116 | if (urlString.length == 0)
117 | {
118 | *outKey = nil;
119 | *outData = @{};
120 | return;
121 | }
122 |
123 | NSURL * url = [NSURL URLWithString:urlString];
124 | if (!url)
125 | {
126 | urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
127 | url = [NSURL URLWithString:urlString];
128 | }
129 |
130 | NSURL* (^urlProcessor)(NSURL*) = [LJRouter sharedInstance].urlProcessorBlock;
131 | if (urlProcessor && url.absoluteString.length)
132 | {
133 | url = urlProcessor(url);
134 | }
135 |
136 | if (url.absoluteString.length == 0 || url.host.length == 0)
137 | {
138 | *outKey = nil;
139 | *outData = @{};
140 | return;
141 | }
142 |
143 | NSMutableString *key = [[NSMutableString alloc] initWithString:url.host];
144 | for (NSString *path in url.pathComponents)
145 | {
146 | if (![path isEqualToString:@"/"])
147 | {
148 | [key appendFormat:@"_%@",path];
149 | }
150 | }
151 | NSDictionary *data = [self uq_URLQueryDictionary:url.query];
152 |
153 | *outKey = key;
154 | *outData = data;
155 | }
156 |
157 | - (BOOL)canOpenUrlString:(NSString *)url
158 | {
159 | NSString *key = nil;
160 | NSDictionary *data = nil;
161 | [self decodeUrlString:url outkey:&key outData:&data];
162 | return [self canRouterKey:key data:data];
163 | }
164 |
165 | - (BOOL)routerUrlString:(NSString *)url
166 | sender:(UIResponder *)sender
167 | pageBlock:(void (^)(__kindof UIViewController *))pageBlock
168 | callbackBlock:(void (^)(NSString *, NSString *, NSString *, BOOL))callbackBlock
169 | canNotRouterBlock:(void (^)(void))canNotRouterBlock
170 | {
171 | NSString *key = nil;
172 | NSDictionary *data = nil;
173 | [self decodeUrlString:url outkey:&key outData:&data];
174 | return [self routerKey:key
175 | data:data
176 | sender:sender
177 | pageBlock:pageBlock
178 | callbackBlock:callbackBlock
179 | canNotRouterBlock:canNotRouterBlock];
180 | }
181 |
182 | @end
183 |
184 |
185 |
--------------------------------------------------------------------------------
/LJRouter/ExportDocument/LJRouterExportDevDocument.m:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // LJRouterExportDevDocument.m
4 | //
5 | // Created by fover0 on 2017/5/31.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | #import
10 | #import
11 |
12 | #import "../ExportTool/LJRouterExportModule.h"
13 |
14 | NSString *getHeaderFilePathWithFilePath(NSString *curPath, NSString* filePath,BOOL isPage)
15 | {
16 | NSArray *paths = [filePath pathComponents];
17 | for (NSInteger i = paths.count - 2; i >=0 ; i--)
18 | {
19 | if ([paths[i] hasSuffix:@"Component"] || [paths[i] hasSuffix:@"Module"] )
20 | {
21 | return [curPath stringByAppendingFormat:@"/%@Header.h",paths[i]];
22 | }
23 | }
24 | return nil;
25 | }
26 |
27 | void writeStringToFile(NSString* string,NSString *file,NSMutableDictionary *opendFiles)
28 | {
29 | if (!file.length)
30 | {
31 | return;
32 | }
33 |
34 | NSNumber *fileIdNumber = opendFiles[file];
35 | if (!fileIdNumber)
36 | {
37 | int fileid = open(file.UTF8String,O_RDWR | O_CREAT | O_TRUNC, S_IRWXU|S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH);
38 | fileIdNumber = [NSNumber numberWithInt:fileid];
39 | opendFiles[file] = fileIdNumber;
40 | }
41 | write(fileIdNumber.intValue, string.UTF8String, strlen(string.UTF8String));
42 | }
43 | void closeAllFile(NSMutableDictionary* opendFiles)
44 | {
45 | [opendFiles enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, NSNumber *obj, BOOL * _Nonnull stop) {
46 | close(obj.intValue);
47 | }];
48 | }
49 |
50 | static void printHeaders(NSMutableDictionary *opendFileId,
51 | NSString *outputPath,
52 | NSArray *items) {
53 | for (NSInteger printAction = 0 ; printAction < 2 ; printAction++)
54 | {
55 | for (LJRegistExportItem *item in items)
56 | {
57 | // 先输出page再输出action
58 | if (printAction == 0 && item.isAction)
59 | {
60 | continue;
61 | }
62 | if (printAction == 1 && !item.isAction)
63 | {
64 | continue;
65 | }
66 | NSString *path = getHeaderFilePathWithFilePath(outputPath,item.filepath, YES);
67 |
68 | NSMutableString *string = [[NSMutableString alloc] init];
69 |
70 | NSString *processedName = [item.keyDescription stringByReplacingOccurrencesOfString:@"//" withString:@"\n//"];
71 |
72 | [string appendFormat:@"// %@ : %@ \n",item.isAction ? @"action":@"页面",processedName];
73 |
74 | [string appendFormat:@"%@(%@",item.isAction ? @"LJRouterUseAction":@"LJRouterUsePage",
75 | item.key];
76 |
77 | if (item.isAction)
78 | {
79 | [string appendFormat:@", %@",item.returnTypeName];
80 | }
81 |
82 | for (LJRegistExportItemParam *param in item.params)
83 | {
84 | [string appendFormat:@", (%@)%@",param.typeName,param.name];
85 | }
86 | [string appendString:@");\n"];
87 |
88 | writeStringToFile(string, path, opendFileId);
89 | }
90 | }
91 | }
92 |
93 | static void printJson(NSArray*items,NSString *exportPath)
94 | {
95 |
96 |
97 | NSMutableArray *pageArray = [[NSMutableArray alloc] init];
98 | NSMutableArray *actionArray = [[NSMutableArray alloc] init];
99 | [items enumerateObjectsUsingBlock:^(LJRegistExportItem * _Nonnull obj,
100 | NSUInteger idx,
101 | BOOL * _Nonnull stop) {
102 | NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
103 | if (obj.isAction)
104 | {
105 | [actionArray addObject:dict];
106 | }
107 | else
108 | {
109 | [pageArray addObject:dict];
110 | }
111 |
112 | dict[@"key"] = obj.key;
113 | dict[@"actionDesc"] = obj.keyDescription;
114 | NSMutableArray *params = [[NSMutableArray alloc] init];
115 | dict[@"parameters"] = params;
116 |
117 | [obj.params enumerateObjectsUsingBlock:^(LJRegistExportItemParam * _Nonnull param, NSUInteger idx, BOOL * _Nonnull stop) {
118 | NSMutableDictionary *paramDict = [[NSMutableDictionary alloc] init];
119 | [params addObject:paramDict];
120 | paramDict[@"name"] = param.name;
121 | }];
122 | }];
123 |
124 | NSError *parseError = nil;
125 | NSData *pageData = [NSJSONSerialization dataWithJSONObject:pageArray
126 | options:NSJSONWritingPrettyPrinted
127 | error:&parseError];
128 | [pageData writeToFile:[exportPath stringByAppendingString:@"/page.json"] atomically:YES];
129 |
130 | NSData *actionData = [NSJSONSerialization dataWithJSONObject:actionArray
131 | options:NSJSONWritingPrettyPrinted
132 | error:&parseError];
133 | [actionData writeToFile:[exportPath stringByAppendingString:@"/action.json"] atomically:YES];
134 | }
135 |
136 | int main(int argc, const char **argv)
137 | {
138 | char* buildDir = getenv("TARGET_BUILD_DIR");
139 | char* execPath = getenv("EXECUTABLE_PATH");
140 | char* projectDir = getenv("PROJECT_DIR");
141 |
142 | if (!buildDir || !execPath || !projectDir || argc < 2)
143 | {
144 | NSLog(@"没有参数");
145 | return 0;
146 | }
147 | BOOL exportJson = NO;
148 | const char *outputDir = "outputHeaders";
149 | for (int i = 1; i < argc; i++)
150 | {
151 | if (strcmp(argv[i],"--json") == 0)
152 | {
153 | exportJson = YES;
154 | }
155 | else
156 | {
157 | outputDir = argv[i];
158 | }
159 | }
160 |
161 |
162 | NSString *path = [[NSString alloc] initWithFormat:@"%s/%s",buildDir,execPath];
163 | NSString *outputPath = [[NSString alloc] initWithFormat:@"%s/%s",projectDir,outputDir];
164 |
165 | NSLog(@"二进制文件为 %@",path);
166 | NSLog(@"输出目录为 %@",outputPath);
167 |
168 | mkdir(outputPath.UTF8String,ALLPERMS);
169 |
170 | NSArray *allItems = loadAllRegItemByPath(path);
171 |
172 | NSMutableDictionary *opendFileId = [[NSMutableDictionary alloc] init];
173 |
174 | // 写页面
175 | printHeaders(opendFileId, outputPath, allItems);
176 |
177 | if (exportJson == YES)
178 | {
179 | printJson(allItems,outputPath);
180 | }
181 |
182 | closeAllFile(opendFileId);
183 | }
184 |
185 |
186 |
--------------------------------------------------------------------------------
/LJRouter/ExportTool/LJRouterExportModule.h:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // LJRouterExportModule.h
4 | //
5 | // Created by fover0 on 2017/5/31.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | #import
10 |
11 | @interface LJRegistExportItemParam : NSObject
12 |
13 | @property (nonatomic, readonly) BOOL isRequire;
14 | @property (nonatomic, readonly) NSString *name;
15 | @property (nonatomic, readonly) NSString *typeName;
16 | @property (nonatomic, readonly) NSString *typeEncoding;
17 |
18 | @end
19 |
20 | @interface LJRegistExportItem : NSObject
21 |
22 | @property (nonatomic, readonly) BOOL isAction;
23 | @property (nonatomic, readonly) NSString *className;
24 | @property (nonatomic, readonly) NSString *categoryName;
25 | @property (nonatomic, readonly) NSString *returnTypeName;
26 | @property (nonatomic, readonly) NSString *returnTypeEncoding;
27 | @property (nonatomic, readonly) NSString *key;
28 | @property (nonatomic, readonly) NSString *keyDescription;
29 | @property (nonatomic, readonly) NSArray *params;
30 | @property (nonatomic, readonly) NSString *selName;
31 | @property (nonatomic, readonly) NSString *filepath;
32 |
33 | @end
34 |
35 | NSArray* loadAllRegItemByPath(NSString* path);
36 |
37 |
--------------------------------------------------------------------------------
/LJRouter/ExportTool/LJRouterExportModule.m:
--------------------------------------------------------------------------------
1 | //
2 | //
3 | // LJRouterExportModule.m
4 | //
5 | // Created by fover0 on 2017/5/31.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 | #import
13 | #import
14 | #import
15 | #import
16 | #import "LJRouterExportModule.h"
17 |
18 | #import "../Core/LJRouterPrivate.h"
19 |
20 | @interface LJRegistExportItemParam ()
21 |
22 | @property (nonatomic, assign) BOOL isRequire;
23 | @property (nonatomic, copy) NSString *name;
24 | @property (nonatomic, copy) NSString *typeName;
25 | @property (nonatomic, copy) NSString *typeEncoding;
26 | @property (nonatomic, copy) NSString *paramDescription;
27 |
28 | @end
29 |
30 | @implementation LJRegistExportItemParam
31 |
32 | - (NSString*)description
33 | {
34 | return [NSString stringWithFormat:@"name:%@\n"
35 | "type:%@\n"
36 | "require:%@",
37 | self.name,
38 | self.typeName,
39 | self.isRequire?@"必须":@"可选"];
40 | }
41 | @end
42 |
43 | @interface LJRegistExportItem ()
44 | @property (nonatomic, assign) BOOL isAction;
45 | @property (nonatomic, copy) NSString *className;
46 | @property (nonatomic, copy) NSString *categoryName;
47 | @property (nonatomic, copy) NSString *returnTypeName;
48 | @property (nonatomic, copy) NSString *returnTypeEncoding;
49 | @property (nonatomic, copy) NSString *returnAttrDesp;
50 | @property (nonatomic, copy) NSString *key;
51 | @property (nonatomic, copy) NSString *keyDescription;
52 | @property (nonatomic, retain) NSArray *params;
53 | @property (nonatomic, copy) NSString *selName;
54 | @property (nonatomic, copy) NSString *filepath;
55 |
56 | @end
57 |
58 | @implementation LJRegistExportItem
59 | - (NSString*)description
60 | {
61 | return [NSString stringWithFormat:@"className:%@\n"
62 | "key:%@\n"
63 | "description:%@",
64 | self.className,
65 | self.key,
66 | self.keyDescription];
67 | }
68 | @end
69 |
70 | // 模拟一个假的结构体 引用C语言的结构体 内存布局是固定的
71 | struct stringstruct {
72 | void* isa;
73 | uint64_t encoding;
74 | char* cstring;
75 | uint64_t len;
76 | };
77 |
78 | static void* getPointerFromAddr(void*data , void* offset)
79 | {
80 | uint8_t *pointer = (uint8_t*)((uint8_t*)data + (uint32_t)offset);
81 | return pointer;
82 | }
83 |
84 | static NSString* getStringFromAddr(void *data, __unsafe_unretained NSString *offset)
85 | {
86 | struct stringstruct *strStruct = getPointerFromAddr(data, (__bridge void*)offset);
87 | char* strPointer = getPointerFromAddr(data, strStruct->cstring);
88 | NSString *string = nil;
89 | if (strStruct->encoding == 0x000007D0) {
90 | string = [[NSString alloc] initWithBytes:strPointer length:strStruct->len * 2 encoding:NSUTF16LittleEndianStringEncoding];
91 | }
92 | else
93 | {
94 | string = [[NSString alloc] initWithBytes:strPointer length:strStruct->len encoding:NSUTF8StringEncoding];
95 | }
96 | return string;
97 | }
98 |
99 | static NSArray* readLJRouterStruct(void *data,struct section_64 *section)
100 | {
101 | uint64_t routerSize = section->size/sizeof(struct LJRouterRegister);
102 | struct LJRouterRegister *Res = (struct LJRouterRegister *)((uint8_t*)data + section->offset);
103 | NSMutableArray *allItems = [[NSMutableArray alloc] init];
104 | for (int k = 0; k < routerSize; k++)
105 | {
106 | LJRegistExportItem *item = [[LJRegistExportItem alloc] init];
107 | [allItems addObject:item];
108 | item.isAction = Res[k].isAction;
109 |
110 | NSString *functionName = [NSString stringWithUTF8String:getPointerFromAddr(data, Res[k].objcFunctionName)];
111 | NSRange range = [functionName rangeOfString:@" "];
112 | functionName = [functionName substringWithRange:NSMakeRange(2, range.location - 2)];
113 | NSString *className = functionName;
114 | NSString *categroyName = nil;
115 | range = [functionName rangeOfString:@"("];
116 | if (range.length != 0)
117 | {
118 | className = [functionName substringToIndex:range.location];
119 | categroyName = [functionName substringWithRange:NSMakeRange(range.location + 1, functionName.length - 2 - className.length)];
120 | }
121 | item.className = className;
122 | item.categoryName = categroyName;
123 |
124 | item.returnTypeName = getStringFromAddr(data, Res[k].returnTypeName);
125 | item.returnTypeEncoding = [NSString stringWithUTF8String: getPointerFromAddr(data, Res[k].returnTypeEncoding)];
126 |
127 | item.key = getStringFromAddr(data, Res[k].key);
128 | item.keyDescription = getStringFromAddr(data, Res[k].keyDescription);
129 | item.selName = getStringFromAddr(data,Res[k].selName);
130 | item.filepath = [[NSString alloc] initWithUTF8String:getPointerFromAddr(data, Res[k].filePath)];
131 |
132 | NSMutableArray *paramsArray = nil;
133 | if (Res[k].paramscount)
134 | {
135 | paramsArray = [[NSMutableArray alloc] init];
136 | }
137 | item.params = paramsArray;
138 |
139 | // params
140 | uint32_t paramscount = Res[k].paramscount;
141 | struct LJRouterRegisterParam *params = getPointerFromAddr(data,Res[k].params);
142 | for(int l = 0; l < paramscount; l++)
143 | {
144 | LJRegistExportItemParam *p = [[LJRegistExportItemParam alloc] init];
145 | p.name = getStringFromAddr(data, params[l].name);
146 | p.typeName = getStringFromAddr(data, params[l].typeName);
147 | const char *typeEncoding = getPointerFromAddr(data, params[l].typeEncoding);
148 | p.typeEncoding = [NSString stringWithUTF8String:typeEncoding] ;
149 | p.isRequire = params[l].isRequire;
150 | [paramsArray addObject:p];
151 | }
152 | }
153 | return allItems;
154 | }
155 |
156 | NSArray* loadAllRegItemByPath(NSString* path)
157 | {
158 | // 全局
159 | NSArray *allItems = nil;
160 |
161 | // 开始工作
162 | if (path.length == 0 || ![[NSFileManager defaultManager] fileExistsAtPath:path]) {
163 | return nil;
164 | }
165 | NSString *file = path;
166 |
167 | int fileid = open(file.UTF8String, 0, O_RDONLY);
168 | off_t len = lseek(fileid, 0, SEEK_END);
169 |
170 | void *data = mmap(NULL,
171 | len,
172 | PROT_READ,
173 | MAP_PRIVATE,
174 | fileid,
175 | 0);
176 | // 最最外层是fat
177 | // 最外层header
178 | struct mach_header_64 header = *((struct mach_header_64*)data);
179 | // NSLog(@"header magic Number is %x",header.magic);
180 | if ((MH_MAGIC_64 != header.magic )&& (MH_CIGAM_64 != header.magic)) { // 忽略32位
181 | close(fileid);
182 | return nil;
183 | }
184 | // 第二层是 command // 强转为uint8是因为不强转 指针转换按照 操作系统长度操作 64位下就是8字节
185 | struct load_command *cmds = (struct load_command *)((uint8_t*)data + sizeof(struct mach_header_64));
186 |
187 | for (uint32_t i = 0 ; i < header.ncmds ; i++,cmds = (struct load_command *)((uint8_t*)cmds + cmds->cmdsize)) {
188 | // 如果是 segment_command_64(一般只关注2种 __DATA,__TEXT)
189 | // 则有第三层 section
190 | if (cmds->cmd != LC_SEGMENT_64) {
191 | continue;
192 | }
193 | struct segment_command_64 *segmentCmd = (struct segment_command_64 *)cmds;
194 | char *name = segmentCmd->segname;
195 | if (0 != strcmp(name, "__DATA")) {
196 | continue;
197 | }
198 | struct section_64 *secions = (struct section_64 *)((uint8_t*)cmds + sizeof(struct segment_command_64));
199 |
200 | for (uint32_t j = 0 ; j < segmentCmd->nsects ; j++, secions += 1)
201 | {
202 | if (0 == strcmp(secions->sectname, "__LJRouter"))
203 | {
204 | allItems = readLJRouterStruct(data, secions);
205 | }
206 | else
207 | {
208 | continue;
209 | }
210 | }
211 | }
212 | close(fileid);
213 | return allItems;
214 | }
215 |
216 |
217 |
218 |
--------------------------------------------------------------------------------
/LJRouter/Navigation/UIViewController+LJNavigation.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewController+LJNavigation.h
3 | // invocation
4 | //
5 | // Created by fover0 on 2017/6/20.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | #import
10 |
11 | typedef NS_ENUM(NSInteger, LJNavigationType)
12 | {
13 | LJNavigationTypePush = 0,
14 | LJNavigationTypePresent = 1,
15 | LJNavigationTypePresentWithNavigation = 2,
16 |
17 | LJNavigationTypeNoAnimation = 1 << 16,
18 | };
19 |
20 | // 对于导航的一些配置
21 | @interface LJNavigationConfig : NSObject
22 |
23 | @property (nonatomic, retain) Class navigationControllerClass;
24 | @property (nonatomic, copy) __kindof UIViewController*(^findTopViewControllerBlock)(void);
25 |
26 | - (void)setup;
27 |
28 | @end
29 |
30 | @interface UIViewController (LJNavigation)
31 |
32 | @property (nonatomic, assign) LJNavigationType ljNavigationType;
33 |
34 | // 自己被别的vc打开时调用 定制当前vc的显示方式 或者弹出登录框等操作
35 | - (void)LJNavigationOpenedByViewController:(__kindof UIViewController*)viewController;
36 |
37 | // 要打开别的vc时调用
38 | - (void)LJNavigationOpenViewController:(__kindof UIViewController*)nextViewController;
39 |
40 | // 当要打开一个vc时 没有当前vc时调用
41 | + (void)LJNavigationOpenViewController:(__kindof UIViewController*)nextViewController;
42 |
43 | - (void)closeSelf;
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/LJRouter/Navigation/UIViewController+LJNavigation.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewController+LJNavigation.m
3 | // invocation
4 | //
5 | // Created by fover0 on 2017/6/20.
6 | // Copyright(c) 2017 Lianjia, Inc. All Rights Reserved
7 | //
8 |
9 | #import "UIViewController+LJNavigation.h"
10 | #import
11 |
12 | static LJNavigationConfig *usedConfig;
13 | @implementation LJNavigationConfig
14 |
15 | - (void)setup
16 | {
17 | usedConfig = self;
18 | }
19 |
20 | @end
21 |
22 | @implementation UIViewController (LJNavigation)
23 |
24 | static char navigationTypeKey;
25 | - (void)setLjNavigationType:(LJNavigationType)ljNavigationType
26 | {
27 | objc_setAssociatedObject(self, &navigationTypeKey, [NSNumber numberWithInteger:ljNavigationType], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
28 | }
29 |
30 | - (LJNavigationType)ljNavigationType
31 | {
32 | return [objc_getAssociatedObject(self, &navigationTypeKey) integerValue];
33 | }
34 |
35 | static char navigationCloseBlockKey;
36 | - (void)setLJNavigationCloseBlock:(void(^)(void))closeBlock
37 | {
38 | objc_setAssociatedObject(self, &navigationCloseBlockKey, [closeBlock copy], OBJC_ASSOCIATION_COPY);
39 | }
40 |
41 | - (void(^)(void))LJNavigationCloseBlock
42 | {
43 | return objc_getAssociatedObject(self, &navigationCloseBlockKey);
44 | }
45 |
46 |
47 | static BOOL tryPushOpen(UIViewController *fromVC,UIViewController *toVC,BOOL animated)
48 | {
49 | if (fromVC.navigationController)
50 | {
51 | [fromVC.navigationController pushViewController:toVC animated:animated];
52 | [toVC setLJNavigationCloseBlock:^{
53 | [fromVC.navigationController popViewControllerAnimated:animated];
54 | }];
55 | return YES;
56 | }
57 | else
58 | {
59 | return tryPresentWithNavigationOpen(fromVC, toVC,animated);
60 | }
61 | }
62 |
63 | static BOOL tryPresentOpen(UIViewController *fromVC,UIViewController *toVC,BOOL animated)
64 | {
65 | [fromVC presentViewController:toVC animated:animated completion:nil];
66 | __weak UIViewController *wvc = toVC;
67 | [toVC setLJNavigationCloseBlock:^{
68 | [wvc dismissViewControllerAnimated:animated completion:nil];
69 | }];
70 | return YES;
71 | }
72 |
73 | static BOOL tryPresentWithNavigationOpen(UIViewController *fromVC,UIViewController *toVC,BOOL animated)
74 | {
75 | Class navClass = Nil;
76 | if ([usedConfig.navigationControllerClass isSubclassOfClass:[UINavigationController class]])
77 | {
78 | navClass = usedConfig.navigationControllerClass;
79 | }
80 | else
81 | {
82 | navClass = [UINavigationController class];
83 | }
84 |
85 | UINavigationController *navVC = [[navClass alloc] initWithRootViewController:toVC];
86 | navVC.modalPresentationStyle = toVC.modalPresentationStyle;
87 | [fromVC presentViewController:navVC animated:animated completion:nil];
88 |
89 | __weak UINavigationController *weakNavVC = navVC;
90 |
91 | [toVC setLJNavigationCloseBlock:^{
92 | UINavigationController *strongNavVC = weakNavVC;
93 | [strongNavVC dismissViewControllerAnimated:animated completion:nil];
94 | }];
95 |
96 | return YES;
97 | }
98 |
99 | // 自己被别的vc打开时调用 定制当前vc的显示方式 或者弹出登录框等操作
100 | - (void)LJNavigationOpenedByViewController:(__kindof UIViewController*)viewController
101 | {
102 | LJNavigationType type = self.ljNavigationType;
103 | BOOL animated = !(type & LJNavigationTypeNoAnimation);
104 | if (!animated)
105 | {
106 | type = type - LJNavigationTypeNoAnimation;
107 | }
108 |
109 | switch (type) {
110 | case LJNavigationTypePush :
111 | tryPushOpen(viewController,self,animated);
112 | break;
113 | case LJNavigationTypePresent :
114 | tryPresentOpen(viewController, self,animated);
115 | break;
116 | case LJNavigationTypePresentWithNavigation :
117 | tryPresentWithNavigationOpen(viewController, self,animated);
118 | break;
119 | default:
120 | // do nothing
121 | break;
122 | }
123 | }
124 |
125 | // 要打开别的vc时调用
126 | - (void)LJNavigationOpenViewController:(__kindof UIViewController*)nextViewController
127 | {
128 | [nextViewController LJNavigationOpenedByViewController:self];
129 | }
130 |
131 | // 当要打开一个vc时 没有当前vc时调用
132 | + (void)LJNavigationOpenViewController:(__kindof UIViewController*)nextViewController
133 | {
134 | UIViewController *curVC = usedConfig.findTopViewControllerBlock ? usedConfig.findTopViewControllerBlock() : nil;
135 | if (!curVC)
136 | {
137 | id appdelegate = [UIApplication sharedApplication].delegate;
138 | UIWindow *window = nil;
139 | // 一般默认生成appdelegate的window属性
140 | if ([appdelegate respondsToSelector:@selector(window)])
141 | {
142 | window = [appdelegate performSelector:@selector(window)];
143 | }
144 | // 如果没有window属性
145 | else
146 | {
147 | if ([UIApplication sharedApplication].windows.count > 0)
148 | {
149 | window = [UIApplication sharedApplication].windows[0];
150 | }
151 | }
152 | curVC = window.rootViewController;
153 | while (1) {
154 | if (curVC.presentingViewController && ![curVC.presentingViewController isKindOfClass:[UIAlertController class]])
155 | {
156 | curVC = curVC.presentingViewController;
157 | }
158 | else if ([curVC isKindOfClass:[UINavigationController class]])
159 | {
160 | UINavigationController *vc = (id)curVC;
161 | curVC = vc.topViewController;
162 | }
163 | else if ([curVC isKindOfClass:[UITabBarController class]])
164 | {
165 | UITabBarController *vc = (id)curVC;
166 | curVC = vc.selectedViewController;
167 | }
168 | else
169 | {
170 | break;
171 | }
172 | }
173 | }
174 | if (curVC)
175 | {
176 | [curVC LJNavigationOpenViewController:nextViewController];
177 | }
178 | else
179 | {
180 | [nextViewController LJNavigationOpenedByViewController:nil];
181 | }
182 | }
183 |
184 | - (void)closeSelf
185 | {
186 | void(^closeBlock)(void) = [self LJNavigationCloseBlock];
187 | if (closeBlock)
188 | {
189 | closeBlock();
190 | }
191 | else
192 | {
193 | BOOL animated = !(self.ljNavigationType & LJNavigationTypeNoAnimation);
194 | if (self.navigationController)
195 | {
196 | if (self.navigationController.viewControllers.count == 1)
197 | {
198 | [self.navigationController dismissViewControllerAnimated:animated completion:nil];
199 | }
200 | else
201 | {
202 | [self.navigationController popViewControllerAnimated:animated];
203 | }
204 | }
205 | else if (self.presentedViewController)
206 | {
207 | [self dismissViewControllerAnimated:animated completion:nil];
208 | }
209 | }
210 | }
211 |
212 |
213 | @end
214 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #LJRouter
2 | ## 0.Example
3 | Example中,请先编译LJRouterExportModule生成文档组件,再运行LJRouter-Example才可生成文档。
4 |
5 | ## 1.接入
6 | ### 1.1 拉取代码
7 | 推荐使用cocoapods进行接入,
8 | 在项目的Podfile中添加如下代码
9 | ```ruby
10 | pod 'LJRouter'
11 | ```
12 | 然后执行 pod install/update
13 | ### 1.2 编译配置
14 | 在项目的BuildPhases的设置中,点击左上角加号,再点击New Run Script Phase.在新出现的Run Script添加如下代码。
15 | ```powershell
16 | ${PODS_ROOT}/LJRouter/build /LJAutogenComponentHeaders
17 | ```
18 | LJAutogenComponentHeaders 可以修改为您需要的名字,后续自动生成的代码会导出到你的项目下该名字的目录中。
19 |
20 | **注意:文件夹只有以Module结尾时被认为是一个模块,该文件夹下的文件才可以生成头文件(递归)**
21 | ### 1.3 添加文件
22 | 进行过 1.1 和 1.2 步骤之后,编译您的代码,然后您会在项目的目录下发现 1.2 中的文件夹,在xcode的源码管理页面中,选择Add files to "xxxxx",然后选择Create folder references,去掉target选项,再选择 步骤1.2 的文件夹,点击Add.后续自动生成的头文件就会出现在该文件夹中了。
23 | `注意:请不要直接引用自动生成的头文件`
24 |
25 | ### 1.4 跳转页面配置
26 | 默认路由只处理分发消息,不处理跳转逻辑,如果搭配LJNavigation使用,请在AppDelegate中添加以下代码。
27 | ```objectivec
28 | [[LJRouter sharedInstance] setOpenControllerWithContextBlock:^(UIViewController *vc, LJRouterSenderContext *senderContext) {
29 | if (senderContext)
30 | {
31 | [senderContext.contextViewController LJNavigationOpenViewController:vc];
32 | }
33 | else
34 | {
35 | [UIViewController LJNavigationOpenViewController:vc];
36 | }
37 | }];
38 | ```
39 | ### 1.5 自定义类型配置(可选)
40 | LJRouter默认支持 数字与字符串的转换,如果您希望将一些其他类型的参数通过外部字符串调用,则需要主动注册一些解析函数,下面的例子是注册一个Json字符串转NSDictionary的例子
41 | ```objectivec
42 | [[LJRouter sharedInstance] addParamConvertTypeBlock:^LJInvocationCenterConvertResult *(id value, NSString *typeName, NSString *typeEncoding) {
43 | if ([typeEncoding isEqualToString:@"@"]
44 | && [typeName hasPrefix:NSStringFromClass([NSDictionary class])])
45 | {
46 | NSData *stringData = [value dataUsingEncoding:NSUTF8StringEncoding];
47 | id json = [NSJSONSerialization JSONObjectWithData:stringData options:0 error:nil];
48 | if ([json isKindOfClass:[NSDictionary class]])
49 | {
50 | return [LJInvocationCenterConvertResult resultWithRetainObj:json];
51 | }
52 | }
53 | return nil;
54 | }];
55 | ```
56 |
57 |
58 |
59 | ## 2 使用
60 | ### 2.1 注册
61 | #### 2.1.1 页面注册
62 | 注册方式如下
63 | ```objectivec
64 | LJRouterInit(@"注释", 页面Key, (类型1)参数名1, (类型2)参数名2, ...) // 没有参数可以不写
65 | ```
66 | 在某ViewController的类中写入以下代码即可完成详情页的注册
67 | ```objectivec
68 | LJRouterInit(@"详情页面", detailPage, (NSString*)someId)
69 | {
70 | self = [self init];
71 | if (self)
72 | {
73 | // 初始化代码
74 | }
75 | return self;
76 | }
77 | ```
78 | #### 2.1.2 action注册
79 | 注册方式如下
80 | ```objectivec
81 | LJRouterInit(@"注释", 页面Key, 返回值类型, (类型1)参数名1, (类型2)参数名2, ...) // 没有参数可以不写
82 | ```
83 | 在任意类的代码中加入如下代码,即可完成一个判断登录状态action的注册.
84 | ``` objectivec
85 | LJRouterRegistAction(@"判断是否登录", isLogin, BOOL)
86 | {
87 | return _isLogin;
88 | }
89 | ```
90 |
91 | #### 2.1.3 注册参数类型的支持
92 | 以上两种注册方式支持任意类型,包括block等.
93 | 1.另外如果您需要某Action与JS通信并返回值,则需要声明一个LJRouterCallbackBlock的参数,调用该参数可以将返回值传递回JS
94 | ``` objectivec
95 | LJRouterRegistAction(@"接收js命令", somejscmd,
96 | void, (NSString*)orignstring,
97 | (LJRouterCallbackBlock)callback)
98 | {
99 | callback([orignstring stringByAppendingString:@"_hello"], YES);
100 | }
101 | ```
102 |
103 | 2.默认要求外部传递所有参数才可通过验证进入到注册的函数,如果您有一个参数不是必须的,则声明为 __nullable即可.(如果是值类型,nullable的变量会默认传0,或者{0,0}这样的结构体)
104 | ```objectivec
105 | LJRouterInit(@"详情页面", detailPage, (NSString*)someId, (__nullable NSString*)title)
106 | {
107 | self = [self init];
108 | if (self)
109 | {
110 | if (title)
111 | {
112 | self.title = title;
113 | }
114 | // 初始化代码
115 | }
116 | return self;
117 | }
118 | ```
119 | 3.如果你的某个注册函数,需要调用者,例如webview中调用设置页面title的action,那么这个action需要声明一个sender参数来接收调用方,sender类型可以是任意UIResponder的子类,或者声明为LJRouterSenderContext,如果直接声明为UIResponder的子类你需要对sender类型进行判断再进行相关的操作。
120 |
121 | 使用LJRouterSenderContext方式如下
122 | ```objectivec
123 | LJRouterRegistAction(@"设置UIWebView标题", setWebViewTitle2,
124 | void, (LJRouterSenderContext*)sender, (NSString*)title)
125 | {
126 | sender.contextViewController.title = title;
127 | }
128 | ```
129 | 使用自定义UIResponder子类方式如下
130 | ```objectivec
131 | LJRouterRegistAction(@"设置UIWebView标题", setWebViewTitle,
132 | void, (UIWebView*)sender, (NSString*)title)
133 | {
134 | if (![sender isKindOfClass:[UIView class]])
135 | {
136 | return;
137 | }
138 | UIResponder *responder = sender ;
139 | while (responder)
140 | {
141 | responder = [responder nextResponder];
142 | if ([responder isKindOfClass:[UIViewController class]])
143 | {
144 | UIViewController *vc = (id)responder;
145 | vc.title = title;
146 | }
147 | }
148 | }
149 | ```
150 | #### 2.1.4 注册key的注意事项
151 | 1.请注意 key会编译为函数的一部分,所以只支持数字字符下划线.
152 | 2.不同的页面注册相同的key会在router启动阶段报错以保证安全.
153 | 3.同一个class可以对同一个key注册多次,但是需要有不同的参数列表,类似java的重载,但是如果某一个参数列表去掉__nullable的参数与另一参数列表相同的话,则有可能发生预期外的行为.
154 | 4.外部调用时,会忽略Key的大小写.
155 | #### 2.1.5 注册的附加属性
156 | 注册之后会默认生成文档,您可以在宏的第一个参数中填写更详尽的解释,同时如果有需求,您也可以为返回值和某个参数单独添加注释,这些注释只会在debug版本使用,并不会增加您发布版本的体积.
157 | 使用方式如下
158 | ```objectivec
159 | LJRouterRegistAction(@"attr测试action有参数", attr_action_1,
160 | NSInteger, (NSString*)something)
161 | {
162 | LJRouterReturnDescription(@"just return int");//为返回值加注释
163 | LJRouterParamDescription(something, @"something ");//为参数加注释
164 | return 0;
165 | }
166 | ```
167 | 生成文档如下
168 | ```objectivec
169 | // action : attr测试action有参数
170 | // @param something something
171 | // @return NSInteger just return int
172 | LJRouterUseAction(attr_action_1, NSInteger, (NSString*)something);
173 | ```
174 |
175 |
176 | ### 2.2 模块间调用
177 | 在-步骤2.1-注册过之后,build项目即可在 -步骤1.2- 设定的文件夹中产生出对应的头文件,示例如下:
178 | ```objectivec
179 | // 页面 : // webview// 外部url
180 | LJRouterUsePage(webview, (NSString*)url);
181 | // action : // 接收js命令// 接收一个字符串 添加_haha结尾
182 | LJRouterUseAction(somejscmd, void, (NSString*)str, (LJRouterCallbackBlock)callback);
183 | // action : // 设置UIWebView标题
184 | LJRouterUseAction(setWebViewTitle, void, (UIWebView*)sender, (NSString*)title);
185 | ```
186 | ####2.2.1 跳转页面
187 | 直接复制头文件中的代码 到你的代码中即可调用 open_Key_controller_的c函数进行跳转 例如
188 | ```objectivec
189 | LJRouterUsePage(webview, (NSString*)url);
190 | - (void)click
191 | {
192 | NSString *url = @"xxxxxx";
193 | open_webview_controller_with_htmlString(self, url);
194 | }
195 | ```
196 | #### 2.2.2 获取页面对象
197 | 如果你想使用某一个页面的对象,而不是直接跳转,可以拷贝头文件的代码后面加Obj结尾,即可调用get_key_controller_的c函数进行获取 例如
198 | ```objectivec
199 | LJRouterUsePageObj(webview, (NSString*)url);
200 | - (void)click2
201 | {
202 | NSString *url = @"xxxxxx";
203 | UIViewController *webVC = get_webview_controller_with_url(url);
204 | // do something ...
205 | }
206 | ```
207 | #### 2.2.3 调用action
208 | 同2.2.1直接复制之后会产生 action_key_xxxx的c函数,直接调用即可
209 |
210 | ### 2.3 外部调用/动态调用
211 | 动态调用请使用下面函数进行调用
212 | ```objectivec
213 | - (BOOL)routerKey:(NSString *)key
214 | data:(NSDictionary *)data
215 | sender:(UIResponder *)sender
216 | pageBlock:(void(^)(__kindof UIViewController* viewController))pageBlock
217 | callbackBlock:(void(^)(NSString *key,
218 | NSString *value,
219 | NSString *data,
220 | BOOL complete))callbackBlock
221 | canNotRouterBlock:(void(^)(void))canNotRouterBlock;
222 |
223 | - (BOOL)routerUrlString:(NSString *)url
224 | sender:(UIResponder *)sender
225 | pageBlock:(void(^)(__kindof UIViewController* viewController))pageBlock
226 | callbackBlock:(void(^)(NSString *key,
227 | NSString *value,
228 | NSString *data,
229 | BOOL complete))callbackBlock
230 | canNotRouterBlock:(void(^)(void))canNotRouterBlock;
231 |
232 | ```
233 | 以上两个函数的区别在于一个接受 key+data形式为数据 一个接受url为数据,内部实现上,url会转化为key+data的形式,默认拆解方式为,问号前面的部分为key,query部分拆解为data。
234 |
235 | 相同的参数部分
236 | **sender**:传入触发该action的UIResponder的子类。
237 | **pageBlock**:是该key分发成功并且为页面时的回调,你应该在这里进行跳转.
238 | **callbackBlock**:分发成功并且存在callbackblock时的回调,一般用该block与webview/js通讯
239 | **canNotRouterBlock**:是不能被分发时的回调
240 |
241 | webview拦截request的通讯方式实现如下
242 | ```objectivec
243 | - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
244 | {
245 | if ([request.URL.scheme hasPrefix:@"lianjia"])
246 | {
247 | return !
248 | [[LJRouter sharedInstance] routerUrlString:request.URL.absoluteString
249 | sender:webView
250 | pageBlock:^(__kindof UIViewController *viewController) {
251 | [[LJRouter sharedInstance] openViewController:viewController withSender:self];
252 | }
253 | callbackBlock:^(NSString *key,
254 | NSString *value,
255 | NSString *data,
256 | BOOL complete) {
257 | if (value.length && data.length)
258 | {
259 | NSString *cmd = [[NSString alloc] initWithFormat:@"%@('%@');",value,data];
260 | [self.webview stringByEvaluatingJavaScriptFromString:cmd];
261 | }
262 | }
263 | canNotRouterBlock:nil];
264 | }
265 | return YES;
266 | }
267 | ```
268 |
269 | ## 3 导出文档的二次开发
270 |
271 | 你可以对导出文档部分进行二次开发,最便捷的方式是在项目中新建一个mac的target,然后将LJRouter/Export/下面的文件加入到target中,然后新建自定义的导出文档的文件,你可以使用 LJRouterExportModule.h中的loadAllRegItemByPath函数读取所有的注册信息.你需要自行管理文档文件,二次开发只提供的基础的读取注册信息的功能.
272 |
273 | ## 4 朋友写的一个源码解析 感兴趣的同学可以看看
274 | [LJRouter源码分析](http://drinking.github.io/ljrouter)
275 |
276 |
--------------------------------------------------------------------------------
/_Pods.xcodeproj:
--------------------------------------------------------------------------------
1 | Example/Pods/Pods.xcodeproj
--------------------------------------------------------------------------------
/build:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | cd ${PODS_ROOT}/LJRouter/
3 | if [ ! -x LJRouterExportDevDocument ];
4 | then
5 | clang -mmacosx-version-min=10.5 -isysroot '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk' -framework Foundation LJRouter/ExportTool/LJRouterExportModule.m LJRouter/ExportDocument/LJRouterExportDevDocument.m -o LJRouterExportDevDocument
6 | fi
7 | cmd="./LJRouterExportDevDocument $*"
8 | echo $cmd
9 | eval $cmd
10 |
--------------------------------------------------------------------------------