├── .DS_Store ├── KTComponentDemo ├── .DS_Store ├── Pod │ ├── .DS_Store │ ├── KTHomeModule │ │ ├── .DS_Store │ │ └── Controllers │ │ │ ├── ViewController.h │ │ │ └── ViewController.m │ ├── KTLoginModule │ │ ├── .DS_Store │ │ ├── KTLoginViewController.h │ │ ├── ModuleHandlerForLogin.h │ │ ├── KTLoginManager.h │ │ ├── KTLoginViewController.m │ │ ├── ModuleHandlerForLogin.m │ │ ├── KTLoginViewController.xib │ │ └── KTLoginManager.m │ ├── KTComponentManager │ │ ├── .DS_Store │ │ ├── KTComponentManager.h │ │ └── KTComponentManager.m │ ├── KTAModule │ │ ├── KTModuleHandlerForA.h │ │ ├── KTAModuleUserViewController.h │ │ ├── KTAModuleUserViewController.m │ │ └── KTModuleHandlerForA.m │ ├── KTAModuleCategory │ │ ├── KTComponentManager+AModule.h │ │ └── KTComponentManager+AModule.m │ └── KTLoginModuleCategory │ │ ├── KTComponentManager+LoginModule.h │ │ └── KTComponentManager+LoginModule.m ├── Assets.xcassets │ ├── Contents.json │ └── AppIcon.appiconset │ │ └── Contents.json ├── AppDelegate.h ├── main.m ├── Info.plist ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard └── AppDelegate.m ├── KTComponentDemo.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcuserdata │ │ └── kiritoSong.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcuserdata │ └── kiritoSong.xcuserdatad │ │ ├── xcschemes │ │ └── xcschememanagement.plist │ │ └── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist └── project.pbxproj ├── README.md ├── KTComponentDemoTests ├── Info.plist └── KTComponentDemoTests.m └── KTComponentDemoUITests ├── Info.plist └── KTComponentDemoUITests.m /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiritoSong/KTComponentDemo/HEAD/.DS_Store -------------------------------------------------------------------------------- /KTComponentDemo/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiritoSong/KTComponentDemo/HEAD/KTComponentDemo/.DS_Store -------------------------------------------------------------------------------- /KTComponentDemo/Pod/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiritoSong/KTComponentDemo/HEAD/KTComponentDemo/Pod/.DS_Store -------------------------------------------------------------------------------- /KTComponentDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTHomeModule/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiritoSong/KTComponentDemo/HEAD/KTComponentDemo/Pod/KTHomeModule/.DS_Store -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTLoginModule/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiritoSong/KTComponentDemo/HEAD/KTComponentDemo/Pod/KTLoginModule/.DS_Store -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTComponentManager/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiritoSong/KTComponentDemo/HEAD/KTComponentDemo/Pod/KTComponentManager/.DS_Store -------------------------------------------------------------------------------- /KTComponentDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /KTComponentDemo.xcodeproj/project.xcworkspace/xcuserdata/kiritoSong.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiritoSong/KTComponentDemo/HEAD/KTComponentDemo.xcodeproj/project.xcworkspace/xcuserdata/kiritoSong.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /KTComponentDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTHomeModule/Controllers/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /KTComponentDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KTComponentDemo 2 | ## [目录](https://www.jianshu.com/p/d5630a3c8516) 3 | - **先说说模块化** 4 | - **如何将中间层与业务层剥离** 5 | - **调用方式** 6 | - **中间件的路由策略** 7 | - **模块入口** 8 | - **低版本兼容** 9 | - **重定向路由** 10 | - **项目的结构** 11 | - **模块化的程度** 12 | - **哪些模块适合下沉** 13 | - **效果演示** 14 | 15 | ![](https://upload-images.jianshu.io/upload_images/1552225-c79efda635ef5ffb.gif?imageMogr2/auto-orient/strip) 16 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTAModule/KTModuleHandlerForA.h: -------------------------------------------------------------------------------- 1 | // 2 | // ModuleAHandler.h 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface KTModuleHandlerForA : NSObject 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTLoginModule/KTLoginViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // KTLoginViewController.h 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface KTLoginViewController : UIViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTLoginModule/ModuleHandlerForLogin.h: -------------------------------------------------------------------------------- 1 | // 2 | // ModuleHandlerForLogin.h 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface ModuleHandlerForLogin : NSObject 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /KTComponentDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /KTComponentDemo.xcodeproj/xcuserdata/kiritoSong.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | KTComponentDemo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTAModule/KTAModuleUserViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ModuleAUserViewController.h 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface KTAModuleUserViewController : UIViewController 14 | - (instancetype)initWithUserName:(NSString *)userName age:(int)age; 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTAModuleCategory/KTComponentManager+AModule.h: -------------------------------------------------------------------------------- 1 | // 2 | // KTComponentManager+ModuleA.h 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import "KTComponentManager.h" 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface KTComponentManager (ModuleA) 15 | 16 | - (UIViewController *)ModuleA_getUserViewControllerWithUserName:(NSString *)userName age:(int)age; 17 | 18 | @end 19 | 20 | NS_ASSUME_NONNULL_END 21 | -------------------------------------------------------------------------------- /KTComponentDemo.xcodeproj/xcuserdata/kiritoSong.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTAModuleCategory/KTComponentManager+AModule.m: -------------------------------------------------------------------------------- 1 | // 2 | // KTComponentManager+ModuleA.m 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import "KTComponentManager+AModule.h" 10 | 11 | 12 | 13 | @implementation KTComponentManager (AModule) 14 | 15 | - (UIViewController *)ModuleA_getUserViewControllerWithUserName:(NSString *)userName age:(int)age { 16 | 17 | return [self openUrl:[NSString stringWithFormat:@"https://www.bilibili.com/KTModuleHandlerForA/getUserViewController?userName=%@&age=%d",userName,age]]; 18 | 19 | 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTLoginModule/KTLoginManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // ModuleLoginLoginManager.h 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | /** 16 | 登录模块 17 | */ 18 | @interface KTLoginManager : NSObject 19 | 20 | 21 | @property (nonatomic ,readonly) BOOL isLogin; 22 | 23 | + (instancetype)sharedInstance; 24 | 25 | /** 26 | 弹窗登录 27 | 28 | @return 是否已经登录 29 | */ 30 | - (BOOL)loginIfNeed; 31 | 32 | 33 | /** 34 | 退出登录 35 | */ 36 | - (void)loginOut; 37 | @end 38 | 39 | NS_ASSUME_NONNULL_END 40 | -------------------------------------------------------------------------------- /KTComponentDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /KTComponentDemoUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTLoginModuleCategory/KTComponentManager+LoginModule.h: -------------------------------------------------------------------------------- 1 | // 2 | // KTComponentManager+ModuleLogin.h 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import "KTComponentManager.h" 10 | 11 | 12 | @protocol KTLoginViewControllerDelegate 13 | 14 | 15 | /** 16 | 登录成功 17 | */ 18 | - (void)didLoginIn; 19 | 20 | 21 | /** 22 | 退出成功 23 | */ 24 | - (void)didLoginOut; 25 | 26 | @end 27 | 28 | NS_ASSUME_NONNULL_BEGIN 29 | 30 | @interface KTComponentManager (LoginModule) 31 | 32 | - (BOOL)isLogin; 33 | 34 | - (BOOL)loginIfNeedWithDelegate:(id)delegate; 35 | 36 | 37 | - (void)loginOutWithDelegate:(id)delegate; 38 | 39 | @end 40 | 41 | NS_ASSUME_NONNULL_END 42 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTComponentManager/KTComponentManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // KTComponentManager.h 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @protocol KTComponentManagerProtocol 15 | 16 | + (id)handleAction:(NSString *)action params:(NSDictionary *)params; 17 | 18 | @end 19 | 20 | @interface KTComponentManager : NSObject 21 | 22 | + (instancetype)sharedInstance; 23 | 24 | 25 | /** 26 | 执行某个已注册的Url 27 | 28 | @param url url 29 | @param params 参数 30 | @return 返回值 31 | */ 32 | - (id)openUrl:(NSString *)url params:(NSDictionary * _Nullable)params; 33 | 34 | 35 | 36 | - (void)addHandleTargetWithInfo:(NSDictionary *)handleInfo; 37 | 38 | - (id)openUrl:(NSString *)url; 39 | @end 40 | 41 | NS_ASSUME_NONNULL_END 42 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTLoginModuleCategory/KTComponentManager+LoginModule.m: -------------------------------------------------------------------------------- 1 | // 2 | // KTComponentManager+ModuleLogin.m 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import "KTComponentManager+LoginModule.h" 10 | 11 | @implementation KTComponentManager (LoginModule) 12 | 13 | - (BOOL)isLogin { 14 | 15 | NSNumber *value = [self openUrl:@"ModuleHandlerForLogin/isLogin" params:nil]; 16 | return [value boolValue]; 17 | } 18 | 19 | 20 | - (BOOL)loginIfNeedWithDelegate:(id)delegate { 21 | 22 | NSNumber *value = [self openUrl:@"ModuleHandlerForLogin/loginIfNeed" params:@{@"delegate":delegate}]; 23 | return [value boolValue]; 24 | } 25 | 26 | - (void)loginOutWithDelegate:(id)delegate { 27 | 28 | [self openUrl:@"ModuleHandlerForLogin/loginOut" params:@{@"delegate":delegate}]; 29 | } 30 | 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTLoginModule/KTLoginViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // KTLoginViewController.m 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import "KTLoginViewController.h" 10 | 11 | @interface KTLoginViewController () 12 | 13 | @end 14 | 15 | @implementation KTLoginViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view from its nib. 20 | } 21 | - (IBAction)loginBtnClick:(UIButton *)sender { 22 | [self dismissViewControllerAnimated:YES completion:nil]; 23 | } 24 | 25 | /* 26 | #pragma mark - Navigation 27 | 28 | // In a storyboard-based application, you will often want to do a little preparation before navigation 29 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 30 | // Get the new view controller using [segue destinationViewController]. 31 | // Pass the selected object to the new view controller. 32 | } 33 | */ 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /KTComponentDemoTests/KTComponentDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // KTComponentDemoTests.m 3 | // KTComponentDemoTests 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface KTComponentDemoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation KTComponentDemoTests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | } 20 | 21 | - (void)tearDown { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | } 24 | 25 | - (void)testExample { 26 | // This is an example of a functional test case. 27 | // Use XCTAssert and related functions to verify your tests produce the correct results. 28 | } 29 | 30 | - (void)testPerformanceExample { 31 | // This is an example of a performance test case. 32 | [self measureBlock:^{ 33 | // Put the code you want to measure the time of here. 34 | }]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /KTComponentDemoUITests/KTComponentDemoUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // KTComponentDemoUITests.m 3 | // KTComponentDemoUITests 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface KTComponentDemoUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation KTComponentDemoUITests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | 20 | // In UI tests it is usually best to stop immediately when a failure occurs. 21 | self.continueAfterFailure = NO; 22 | 23 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 24 | [[[XCUIApplication alloc] init] launch]; 25 | 26 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 27 | } 28 | 29 | - (void)tearDown { 30 | // Put teardown code here. This method is called after the invocation of each test method in the class. 31 | } 32 | 33 | - (void)testExample { 34 | // Use recording to get started writing UI tests. 35 | // Use XCTAssert and related functions to verify your tests produce the correct results. 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTLoginModule/ModuleHandlerForLogin.m: -------------------------------------------------------------------------------- 1 | // 2 | // ModuleHandlerForLogin.m 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import "ModuleHandlerForLogin.h" 10 | #import "KTLoginManager.h" 11 | #import "KTComponentManager+LoginModule.h" 12 | 13 | @implementation ModuleHandlerForLogin 14 | 15 | /** 16 | 相当于每个模块维护自己的注册表 17 | */ 18 | + (id)handleAction:(NSString *)action params:(NSDictionary *)params { 19 | id returnValue = nil; 20 | 21 | //这里代理懒得在往下传了 22 | id delegate = params[@"delegate"]; 23 | 24 | if ([action isEqualToString:@"isLogin"]) { 25 | 26 | returnValue = @([[KTLoginManager sharedInstance] isLogin]); 27 | } 28 | if ([action isEqualToString:@"loginIfNeed"]) { 29 | 30 | returnValue = @([[KTLoginManager sharedInstance] loginIfNeed]); 31 | if ([delegate respondsToSelector:@selector(didLoginIn)]) { 32 | [delegate didLoginIn]; 33 | } 34 | 35 | } 36 | 37 | if ([action isEqualToString:@"loginOut"]) { 38 | 39 | [[KTLoginManager sharedInstance] loginOut]; 40 | if ([delegate respondsToSelector:@selector(didLoginOut)]) { 41 | [delegate didLoginOut]; 42 | } 43 | 44 | } 45 | return returnValue; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTAModule/KTAModuleUserViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ModuleAUserViewController.m 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import "KTAModuleUserViewController.h" 10 | 11 | @interface KTAModuleUserViewController () 12 | { 13 | NSString *_userName; 14 | int _age; 15 | } 16 | @end 17 | 18 | @implementation KTAModuleUserViewController 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | // Do any additional setup after loading the view. 23 | self.view.backgroundColor = [UIColor whiteColor]; 24 | UILabel *nameLab = [UILabel new]; 25 | nameLab.frame = CGRectMake(50, 100, 300, 100); 26 | nameLab.backgroundColor = [UIColor orangeColor]; 27 | nameLab.text = [NSString stringWithFormat:@"姓名:%@",_userName]; 28 | [self.view addSubview:nameLab]; 29 | 30 | 31 | UILabel *ageLab = [UILabel new]; 32 | ageLab.frame = CGRectMake(50, 300, 300, 100); 33 | ageLab.backgroundColor = [UIColor orangeColor]; 34 | ageLab.text = [NSString stringWithFormat:@"年龄:%d",_age]; 35 | [self.view addSubview:ageLab]; 36 | 37 | } 38 | 39 | - (instancetype)initWithUserName:(NSString *)userName age:(int)age 40 | { 41 | self = [super init]; 42 | if (self) { 43 | _userName = userName; 44 | _age = age; 45 | } 46 | return self; 47 | } 48 | 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /KTComponentDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /KTComponentDemo/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 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTHomeModule/Controllers/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "KTComponentManager+AModule.h" 11 | #import "KTComponentManager+LoginModule.h" 12 | 13 | 14 | @interface ViewController () 15 | @property (weak, nonatomic) IBOutlet UIButton *loginBtn; 16 | 17 | @end 18 | 19 | @implementation ViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | // Do any additional setup after loading the view, typically from a nib. 24 | 25 | 26 | } 27 | 28 | - (IBAction)pushToModuleAUserVC:(UIButton *)sender { 29 | 30 | if (![[KTComponentManager sharedInstance] loginIfNeedWithDelegate:self]) { 31 | return; 32 | } 33 | 34 | UIViewController * vc = [[KTComponentManager sharedInstance] ModuleA_getUserViewControllerWithUserName:@"kirito" age:18]; 35 | [self.navigationController pushViewController:vc animated:YES]; 36 | 37 | } 38 | - (IBAction)LoginBtnClick:(UIButton *)sender { 39 | 40 | if ([[KTComponentManager sharedInstance] loginIfNeedWithDelegate:self]) { 41 | [[KTComponentManager sharedInstance] loginOutWithDelegate:self]; 42 | } 43 | 44 | } 45 | 46 | - (IBAction)openWebUrl:(id)sender { 47 | [[KTComponentManager sharedInstance] openUrl:[NSString stringWithFormat:@"https://www.bilibili.com/video/av25305807"]]; 48 | } 49 | 50 | //这里应该用通知获取的 51 | - (void)didLoginIn { 52 | [self.loginBtn setTitle:@"退出登录" forState:UIControlStateNormal]; 53 | } 54 | 55 | - (void)didLoginOut { 56 | [self.loginBtn setTitle:@"登录" forState:UIControlStateNormal]; 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTAModule/KTModuleHandlerForA.m: -------------------------------------------------------------------------------- 1 | // 2 | // ModuleAHandler.m 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import "KTModuleHandlerForA.h" 10 | #import "KTAModuleUserViewController.h" 11 | 12 | @implementation KTModuleHandlerForA 13 | 14 | /** 15 | 在load中向组件管理器注册 16 | 17 | 这里其实如果引入KTComponentManager会方便很多 18 | 但是会依赖管理中心、所以算了 19 | 20 | */ 21 | + (void)load { 22 | 23 | #pragma clang diagnostic push 24 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 25 | 26 | Class KTComponentManagerClass = NSClassFromString(@"KTComponentManager"); 27 | SEL sharedInstance = NSSelectorFromString(@"sharedInstance"); 28 | id KTComponentManager = [KTComponentManagerClass performSelector:sharedInstance]; 29 | SEL addHandleTargetWithInfo = NSSelectorFromString(@"addHandleTargetWithInfo:"); 30 | 31 | NSMutableSet * actionSet = [[NSMutableSet alloc]initWithArray:@[@"getUserViewController"]]; 32 | 33 | NSDictionary * targetInfo = @{ 34 | @"targetName":@"KTModuleHandlerForA", 35 | @"actionSet":actionSet 36 | }; 37 | 38 | [KTComponentManager performSelector:addHandleTargetWithInfo withObject:targetInfo]; 39 | 40 | #pragma clang diagnostic pop 41 | 42 | } 43 | 44 | 45 | 46 | 47 | /** 48 | 相当于每个模块维护自己的注册表 49 | */ 50 | + (id)handleAction:(NSString *)action params:(NSDictionary *)params { 51 | id returnValue = nil; 52 | if ([action isEqualToString:@"getUserViewController"]) { 53 | 54 | returnValue = [[KTAModuleUserViewController alloc]initWithUserName:params[@"userName"] age:[params[@"age"] intValue]]; 55 | } 56 | return returnValue; 57 | } 58 | @end 59 | -------------------------------------------------------------------------------- /KTComponentDemo/Assets.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 | } -------------------------------------------------------------------------------- /KTComponentDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // 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. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // 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. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // 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. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTLoginModule/KTLoginViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTLoginModule/KTLoginManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // ModuleLoginLoginManager.m 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import "KTLoginManager.h" 10 | #import "KTLoginViewController.h" 11 | 12 | 13 | @interface KTLoginManager () 14 | @property (nonatomic ,readwrite) BOOL isLogin; 15 | @end 16 | 17 | @implementation KTLoginManager 18 | 19 | + (instancetype)sharedInstance 20 | { 21 | static KTLoginManager *mediator; 22 | static dispatch_once_t onceToken; 23 | dispatch_once(&onceToken, ^{ 24 | mediator = [[KTLoginManager alloc] init]; 25 | }); 26 | return mediator; 27 | } 28 | 29 | 30 | -(BOOL)loginIfNeed { 31 | 32 | if (!_isLogin) { 33 | UIViewController * getCurrentVC = [KTLoginManager getCurrentVC]; 34 | KTLoginViewController * loginVC = [KTLoginViewController new]; 35 | [getCurrentVC presentViewController:loginVC animated:YES completion:nil]; 36 | _isLogin = YES; 37 | return NO; 38 | } 39 | return _isLogin; 40 | } 41 | 42 | 43 | - (void)loginOut { 44 | _isLogin = NO; 45 | } 46 | 47 | +(UIViewController *)getCurrentVC{ 48 | UIViewController *result = nil; 49 | UIWindow * window = [[UIApplication sharedApplication].delegate window]; 50 | //app默认windowLevel是UIWindowLevelNormal,如果不是,找到UIWindowLevelNormal的 51 | if (window.windowLevel != UIWindowLevelNormal) 52 | { 53 | NSArray *windows = [[UIApplication sharedApplication] windows]; 54 | for(UIWindow * tmpWin in windows) 55 | { 56 | if (tmpWin.windowLevel == UIWindowLevelNormal) 57 | { 58 | window = tmpWin; 59 | break; 60 | } 61 | } 62 | } 63 | id nextResponder = nil; 64 | UIViewController *appRootVC=window.rootViewController; 65 | // 如果是present上来的appRootVC.presentedViewController 不为nil 66 | if (appRootVC.presentedViewController) { 67 | //多层present 68 | while (appRootVC.presentedViewController) { 69 | appRootVC = appRootVC.presentedViewController; 70 | if (appRootVC) { 71 | nextResponder = appRootVC; 72 | }else{ 73 | break; 74 | } 75 | } 76 | // nextResponder = appRootVC.presentedViewController; 77 | }else{ 78 | 79 | // 如果当前UIViewController顶层不是UIView,那就需要循环获取到该UIViewController对应的UIView, 80 | // 才能跳出循环 81 | int i= 0; 82 | UIView *frontView = [[window subviews] objectAtIndex:i]; 83 | nextResponder = [frontView nextResponder]; 84 | while (![nextResponder isKindOfClass:[UIViewController class]]) { 85 | i++; 86 | frontView = [[window subviews]objectAtIndex:i]; 87 | nextResponder = [frontView nextResponder]; 88 | } 89 | } 90 | 91 | if ([nextResponder isKindOfClass:[UITabBarController class]]){ 92 | UITabBarController * tabbar = (UITabBarController *)nextResponder; 93 | UINavigationController * nav = (UINavigationController *)tabbar.viewControllers[tabbar.selectedIndex]; 94 | // UINavigationController * nav = tabbar.selectedViewController ; 上下两种写法都行 95 | result=nav.childViewControllers.lastObject; 96 | 97 | }else if ([nextResponder isKindOfClass:[UINavigationController class]]){ 98 | UIViewController * nav = (UIViewController *)nextResponder; 99 | result = nav.childViewControllers.lastObject; 100 | }else{ 101 | result = nextResponder; 102 | } 103 | return result; 104 | } 105 | 106 | 107 | @end 108 | -------------------------------------------------------------------------------- /KTComponentDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 43 | 50 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /KTComponentDemo/Pod/KTComponentManager/KTComponentManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // KTComponentManager.m 3 | // KTComponentDemo 4 | // 5 | // Created by 刘嵩野 on 2018/10/25. 6 | // Copyright © 2018年 kirito_song. All rights reserved. 7 | // 8 | 9 | #import "KTComponentManager.h" 10 | 11 | @interface KTComponentManager () 12 | 13 | @property (nonatomic) NSDictionary *registeredDic; 14 | 15 | @property (nonatomic) NSDictionary *redirectionjson; 16 | 17 | @property (nonatomic) NSMutableSet * webUrlSet; 18 | 19 | @end 20 | 21 | @implementation KTComponentManager 22 | 23 | + (instancetype)sharedInstance 24 | { 25 | static KTComponentManager *mediator; 26 | static dispatch_once_t onceToken; 27 | dispatch_once(&onceToken, ^{ 28 | mediator = [[KTComponentManager alloc] init]; 29 | }); 30 | return mediator; 31 | } 32 | 33 | - (id)openUrl:(NSString *)url{ 34 | id returnObj; 35 | 36 | NSURL * openUrl = [NSURL URLWithString:url]; 37 | NSString * path = [openUrl.path substringWithRange:NSMakeRange(1, openUrl.path.length - 1)]; 38 | 39 | NSRange range = [path rangeOfString:@"/"]; 40 | NSString *targetName = [path substringWithRange:NSMakeRange(0, range.location)]; 41 | NSString *actionName = [path substringWithRange:NSMakeRange(range.location + 1, path.length - range.location - 1)]; 42 | 43 | //可以对url进行路由。比如从服务器下发json文件。将AAAA/BBBB路由到AAAA/DDDD或者CCCC/EEEE这样 44 | if (self.redirectionjson[path]) { 45 | path = self.redirectionjson[path]; 46 | } 47 | 48 | //如果该target的action已经注册 49 | if ([self.registeredDic[targetName] containsObject:actionName]) { 50 | returnObj = [self openUrl:path params:[self getURLParameters:openUrl.absoluteString]]; 51 | }else if ([self.webUrlSet containsObject:[NSString stringWithFormat:@"%@%@",openUrl.host,openUrl.path]]){ 52 | //低版本兼容 53 | //如果有某些H5页面、打开H5页面 54 | //webUrlSet可以由服务器下发 55 | NSLog(@"跳转网页:%@",url); 56 | } 57 | 58 | return returnObj; 59 | } 60 | 61 | 62 | - (id)openUrl:(NSString *)url params:(NSDictionary *)params { 63 | id returnObj; 64 | 65 | if (url.length == 0) { 66 | return nil; 67 | } 68 | 69 | //可以对url进行路由。比如从服务器下发json文件。将AAAA/BBBB路由到AAAA/DDDD或者CCCC/EEEE这样 70 | if (self.redirectionjson[url]) { 71 | url = self.redirectionjson[url]; 72 | } 73 | 74 | 75 | NSRange range = [url rangeOfString:@"/"]; 76 | 77 | NSString *targetName = [url substringWithRange:NSMakeRange(0, range.location)]; 78 | NSString *actionName = [url substringWithRange:NSMakeRange(range.location + 1, url.length - range.location - 1)]; 79 | 80 | 81 | Class targetClass = NSClassFromString(targetName); 82 | 83 | 84 | if ([targetClass respondsToSelector:@selector(handleAction:params:)]) { 85 | //向已经实现了协议的对象发送Target&&Action信息 86 | returnObj = [targetClass handleAction:actionName params:params]; 87 | }else { 88 | //未注册的、进行进一步处理。比如上报啊、返回一个占位对象啊等等 89 | NSLog(@"未注册的方法"); 90 | } 91 | 92 | return returnObj; 93 | } 94 | 95 | 96 | - (void)addHandleTargetWithInfo:(NSDictionary *)handleInfo { 97 | [self.registeredDic setValue:handleInfo[@"actionSet"] forKey:handleInfo[@"targetName"]]; 98 | } 99 | 100 | 101 | 102 | - (NSMutableDictionary *)getURLParameters:(NSString *)urlStr { 103 | 104 | // 查找参数 105 | NSRange range = [urlStr rangeOfString:@"?"]; 106 | if (range.location == NSNotFound) { 107 | return nil; 108 | } 109 | 110 | // 以字典形式将参数返回 111 | NSMutableDictionary *params = [NSMutableDictionary dictionary]; 112 | 113 | // 截取参数 114 | NSString *parametersString = [urlStr substringFromIndex:range.location + 1]; 115 | 116 | // 判断参数是单个参数还是多个参数 117 | if ([parametersString containsString:@"&"]) { 118 | 119 | // 多个参数,分割参数 120 | NSArray *urlComponents = [parametersString componentsSeparatedByString:@"&"]; 121 | 122 | for (NSString *keyValuePair in urlComponents) { 123 | // 生成Key/Value 124 | NSArray *pairComponents = [keyValuePair componentsSeparatedByString:@"="]; 125 | NSString *key = [pairComponents.firstObject stringByRemovingPercentEncoding]; 126 | NSString *value = [pairComponents.lastObject stringByRemovingPercentEncoding]; 127 | 128 | // Key不能为nil 129 | if (key == nil || value == nil) { 130 | continue; 131 | } 132 | 133 | id existValue = [params valueForKey:key]; 134 | 135 | if (existValue != nil) { 136 | 137 | // 已存在的值,生成数组 138 | if ([existValue isKindOfClass:[NSArray class]]) { 139 | // 已存在的值生成数组 140 | NSMutableArray *items = [NSMutableArray arrayWithArray:existValue]; 141 | [items addObject:value]; 142 | 143 | [params setValue:items forKey:key]; 144 | } else { 145 | 146 | // 非数组 147 | [params setValue:@[existValue, value] forKey:key]; 148 | } 149 | 150 | } else { 151 | 152 | // 设置值 153 | [params setValue:value forKey:key]; 154 | } 155 | } 156 | } else { 157 | // 单个参数 158 | 159 | // 生成Key/Value 160 | NSArray *pairComponents = [parametersString componentsSeparatedByString:@"="]; 161 | 162 | // 只有一个参数,没有值 163 | if (pairComponents.count == 1) { 164 | return nil; 165 | } 166 | 167 | // 分隔值 168 | NSString *key = [pairComponents.firstObject stringByRemovingPercentEncoding]; 169 | NSString *value = [pairComponents.lastObject stringByRemovingPercentEncoding]; 170 | 171 | // Key不能为nil 172 | if (key == nil || value == nil) { 173 | return nil; 174 | } 175 | 176 | // 设置值 177 | [params setValue:value forKey:key]; 178 | } 179 | 180 | return params; 181 | } 182 | 183 | - (NSDictionary *)registeredDic { 184 | if (!_registeredDic) { 185 | _registeredDic = [NSMutableDictionary new]; 186 | } 187 | return _registeredDic; 188 | } 189 | 190 | - (NSMutableSet *)webUrlSet { 191 | if (!_webUrlSet) { 192 | _webUrlSet = [[NSMutableSet alloc]initWithObjects:@"www.bilibili.com/video/av25305807", nil]; 193 | } 194 | return _webUrlSet; 195 | } 196 | @end 197 | -------------------------------------------------------------------------------- /KTComponentDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5FAA97DC218162F200333DE8 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FAA97DB218162F200333DE8 /* AppDelegate.m */; }; 11 | 5FAA97E2218162F200333DE8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5FAA97E0218162F200333DE8 /* Main.storyboard */; }; 12 | 5FAA97E4218162F400333DE8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5FAA97E3218162F400333DE8 /* Assets.xcassets */; }; 13 | 5FAA97E7218162F400333DE8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5FAA97E5218162F400333DE8 /* LaunchScreen.storyboard */; }; 14 | 5FAA97EA218162F400333DE8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FAA97E9218162F400333DE8 /* main.m */; }; 15 | 5FAA97F4218162F400333DE8 /* KTComponentDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FAA97F3218162F400333DE8 /* KTComponentDemoTests.m */; }; 16 | 5FAA97FF218162F400333DE8 /* KTComponentDemoUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FAA97FE218162F400333DE8 /* KTComponentDemoUITests.m */; }; 17 | 5FAA98152181651000333DE8 /* KTComponentManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FAA98142181651000333DE8 /* KTComponentManager.m */; }; 18 | 5FAA982E21818C4700333DE8 /* ModuleHandlerForLogin.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FAA982A21818C4700333DE8 /* ModuleHandlerForLogin.m */; }; 19 | 5FAA982F21818C4700333DE8 /* KTLoginManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FAA982B21818C4700333DE8 /* KTLoginManager.m */; }; 20 | 5FAA983521818C5700333DE8 /* KTAModuleUserViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FAA983121818C5700333DE8 /* KTAModuleUserViewController.m */; }; 21 | 5FAA983621818C5700333DE8 /* KTModuleHandlerForA.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FAA983221818C5700333DE8 /* KTModuleHandlerForA.m */; }; 22 | 5FAA983D21818CAD00333DE8 /* KTComponentManager+AModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FAA983821818CAC00333DE8 /* KTComponentManager+AModule.m */; }; 23 | 5FAA983E21818CAD00333DE8 /* KTComponentManager+LoginModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FAA983B21818CAC00333DE8 /* KTComponentManager+LoginModule.m */; }; 24 | 5FAA98452181900C00333DE8 /* KTLoginViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FAA98432181900C00333DE8 /* KTLoginViewController.m */; }; 25 | 5FAA98462181900C00333DE8 /* KTLoginViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5FAA98442181900C00333DE8 /* KTLoginViewController.xib */; }; 26 | 5FAA984D2181BF6200333DE8 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5FAA98492181BF6200333DE8 /* ViewController.m */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXContainerItemProxy section */ 30 | 5FAA97F0218162F400333DE8 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = 5FAA97CF218162F200333DE8 /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = 5FAA97D6218162F200333DE8; 35 | remoteInfo = KTComponentDemo; 36 | }; 37 | 5FAA97FB218162F400333DE8 /* PBXContainerItemProxy */ = { 38 | isa = PBXContainerItemProxy; 39 | containerPortal = 5FAA97CF218162F200333DE8 /* Project object */; 40 | proxyType = 1; 41 | remoteGlobalIDString = 5FAA97D6218162F200333DE8; 42 | remoteInfo = KTComponentDemo; 43 | }; 44 | /* End PBXContainerItemProxy section */ 45 | 46 | /* Begin PBXFileReference section */ 47 | 5FAA97D7218162F200333DE8 /* KTComponentDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KTComponentDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | 5FAA97DA218162F200333DE8 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 49 | 5FAA97DB218162F200333DE8 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 50 | 5FAA97E1218162F200333DE8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 51 | 5FAA97E3218162F400333DE8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 52 | 5FAA97E6218162F400333DE8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 53 | 5FAA97E8218162F400333DE8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | 5FAA97E9218162F400333DE8 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 55 | 5FAA97EF218162F400333DE8 /* KTComponentDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KTComponentDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | 5FAA97F3218162F400333DE8 /* KTComponentDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KTComponentDemoTests.m; sourceTree = ""; }; 57 | 5FAA97F5218162F400333DE8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | 5FAA97FA218162F400333DE8 /* KTComponentDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KTComponentDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 59 | 5FAA97FE218162F400333DE8 /* KTComponentDemoUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KTComponentDemoUITests.m; sourceTree = ""; }; 60 | 5FAA9800218162F400333DE8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 61 | 5FAA98132181651000333DE8 /* KTComponentManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KTComponentManager.h; sourceTree = ""; }; 62 | 5FAA98142181651000333DE8 /* KTComponentManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KTComponentManager.m; sourceTree = ""; }; 63 | 5FAA982A21818C4700333DE8 /* ModuleHandlerForLogin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ModuleHandlerForLogin.m; sourceTree = ""; }; 64 | 5FAA982B21818C4700333DE8 /* KTLoginManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KTLoginManager.m; sourceTree = ""; }; 65 | 5FAA982C21818C4700333DE8 /* ModuleHandlerForLogin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModuleHandlerForLogin.h; sourceTree = ""; }; 66 | 5FAA982D21818C4700333DE8 /* KTLoginManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTLoginManager.h; sourceTree = ""; }; 67 | 5FAA983121818C5700333DE8 /* KTAModuleUserViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KTAModuleUserViewController.m; sourceTree = ""; }; 68 | 5FAA983221818C5700333DE8 /* KTModuleHandlerForA.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KTModuleHandlerForA.m; sourceTree = ""; }; 69 | 5FAA983321818C5700333DE8 /* KTAModuleUserViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTAModuleUserViewController.h; sourceTree = ""; }; 70 | 5FAA983421818C5700333DE8 /* KTModuleHandlerForA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KTModuleHandlerForA.h; sourceTree = ""; }; 71 | 5FAA983821818CAC00333DE8 /* KTComponentManager+AModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "KTComponentManager+AModule.m"; sourceTree = ""; }; 72 | 5FAA983921818CAC00333DE8 /* KTComponentManager+AModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KTComponentManager+AModule.h"; sourceTree = ""; }; 73 | 5FAA983B21818CAC00333DE8 /* KTComponentManager+LoginModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "KTComponentManager+LoginModule.m"; sourceTree = ""; }; 74 | 5FAA983C21818CAC00333DE8 /* KTComponentManager+LoginModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KTComponentManager+LoginModule.h"; sourceTree = ""; }; 75 | 5FAA98422181900C00333DE8 /* KTLoginViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KTLoginViewController.h; sourceTree = ""; }; 76 | 5FAA98432181900C00333DE8 /* KTLoginViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KTLoginViewController.m; sourceTree = ""; }; 77 | 5FAA98442181900C00333DE8 /* KTLoginViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = KTLoginViewController.xib; sourceTree = ""; }; 78 | 5FAA98492181BF6200333DE8 /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 79 | 5FAA984A2181BF6200333DE8 /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 80 | /* End PBXFileReference section */ 81 | 82 | /* Begin PBXFrameworksBuildPhase section */ 83 | 5FAA97D4218162F200333DE8 /* Frameworks */ = { 84 | isa = PBXFrameworksBuildPhase; 85 | buildActionMask = 2147483647; 86 | files = ( 87 | ); 88 | runOnlyForDeploymentPostprocessing = 0; 89 | }; 90 | 5FAA97EC218162F400333DE8 /* Frameworks */ = { 91 | isa = PBXFrameworksBuildPhase; 92 | buildActionMask = 2147483647; 93 | files = ( 94 | ); 95 | runOnlyForDeploymentPostprocessing = 0; 96 | }; 97 | 5FAA97F7218162F400333DE8 /* Frameworks */ = { 98 | isa = PBXFrameworksBuildPhase; 99 | buildActionMask = 2147483647; 100 | files = ( 101 | ); 102 | runOnlyForDeploymentPostprocessing = 0; 103 | }; 104 | /* End PBXFrameworksBuildPhase section */ 105 | 106 | /* Begin PBXGroup section */ 107 | 5FAA97CE218162F200333DE8 = { 108 | isa = PBXGroup; 109 | children = ( 110 | 5FAA97D9218162F200333DE8 /* KTComponentDemo */, 111 | 5FAA97F2218162F400333DE8 /* KTComponentDemoTests */, 112 | 5FAA97FD218162F400333DE8 /* KTComponentDemoUITests */, 113 | 5FAA97D8218162F200333DE8 /* Products */, 114 | ); 115 | sourceTree = ""; 116 | }; 117 | 5FAA97D8218162F200333DE8 /* Products */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | 5FAA97D7218162F200333DE8 /* KTComponentDemo.app */, 121 | 5FAA97EF218162F400333DE8 /* KTComponentDemoTests.xctest */, 122 | 5FAA97FA218162F400333DE8 /* KTComponentDemoUITests.xctest */, 123 | ); 124 | name = Products; 125 | sourceTree = ""; 126 | }; 127 | 5FAA97D9218162F200333DE8 /* KTComponentDemo */ = { 128 | isa = PBXGroup; 129 | children = ( 130 | 5FAA980C218163EF00333DE8 /* Pod */, 131 | 5FAA97DA218162F200333DE8 /* AppDelegate.h */, 132 | 5FAA97DB218162F200333DE8 /* AppDelegate.m */, 133 | 5FAA97E0218162F200333DE8 /* Main.storyboard */, 134 | 5FAA97E3218162F400333DE8 /* Assets.xcassets */, 135 | 5FAA97E5218162F400333DE8 /* LaunchScreen.storyboard */, 136 | 5FAA97E8218162F400333DE8 /* Info.plist */, 137 | 5FAA97E9218162F400333DE8 /* main.m */, 138 | ); 139 | path = KTComponentDemo; 140 | sourceTree = ""; 141 | }; 142 | 5FAA97F2218162F400333DE8 /* KTComponentDemoTests */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 5FAA97F3218162F400333DE8 /* KTComponentDemoTests.m */, 146 | 5FAA97F5218162F400333DE8 /* Info.plist */, 147 | ); 148 | path = KTComponentDemoTests; 149 | sourceTree = ""; 150 | }; 151 | 5FAA97FD218162F400333DE8 /* KTComponentDemoUITests */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | 5FAA97FE218162F400333DE8 /* KTComponentDemoUITests.m */, 155 | 5FAA9800218162F400333DE8 /* Info.plist */, 156 | ); 157 | path = KTComponentDemoUITests; 158 | sourceTree = ""; 159 | }; 160 | 5FAA980C218163EF00333DE8 /* Pod */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | 5FAA983721818CAC00333DE8 /* KTAModuleCategory */, 164 | 5FAA983A21818CAC00333DE8 /* KTLoginModuleCategory */, 165 | 5FAA98472181933600333DE8 /* KTHomeModule */, 166 | 5FAA983021818C5700333DE8 /* KTAModule */, 167 | 5FAA982921818C4700333DE8 /* KTLoginModule */, 168 | 5FAA980D218163EF00333DE8 /* KTComponentManager */, 169 | ); 170 | path = Pod; 171 | sourceTree = ""; 172 | }; 173 | 5FAA980D218163EF00333DE8 /* KTComponentManager */ = { 174 | isa = PBXGroup; 175 | children = ( 176 | 5FAA98132181651000333DE8 /* KTComponentManager.h */, 177 | 5FAA98142181651000333DE8 /* KTComponentManager.m */, 178 | ); 179 | path = KTComponentManager; 180 | sourceTree = ""; 181 | }; 182 | 5FAA982921818C4700333DE8 /* KTLoginModule */ = { 183 | isa = PBXGroup; 184 | children = ( 185 | 5FAA982C21818C4700333DE8 /* ModuleHandlerForLogin.h */, 186 | 5FAA982A21818C4700333DE8 /* ModuleHandlerForLogin.m */, 187 | 5FAA982D21818C4700333DE8 /* KTLoginManager.h */, 188 | 5FAA982B21818C4700333DE8 /* KTLoginManager.m */, 189 | 5FAA98422181900C00333DE8 /* KTLoginViewController.h */, 190 | 5FAA98432181900C00333DE8 /* KTLoginViewController.m */, 191 | 5FAA98442181900C00333DE8 /* KTLoginViewController.xib */, 192 | ); 193 | path = KTLoginModule; 194 | sourceTree = ""; 195 | }; 196 | 5FAA983021818C5700333DE8 /* KTAModule */ = { 197 | isa = PBXGroup; 198 | children = ( 199 | 5FAA983321818C5700333DE8 /* KTAModuleUserViewController.h */, 200 | 5FAA983121818C5700333DE8 /* KTAModuleUserViewController.m */, 201 | 5FAA983421818C5700333DE8 /* KTModuleHandlerForA.h */, 202 | 5FAA983221818C5700333DE8 /* KTModuleHandlerForA.m */, 203 | ); 204 | path = KTAModule; 205 | sourceTree = ""; 206 | }; 207 | 5FAA983721818CAC00333DE8 /* KTAModuleCategory */ = { 208 | isa = PBXGroup; 209 | children = ( 210 | 5FAA983921818CAC00333DE8 /* KTComponentManager+AModule.h */, 211 | 5FAA983821818CAC00333DE8 /* KTComponentManager+AModule.m */, 212 | ); 213 | path = KTAModuleCategory; 214 | sourceTree = ""; 215 | }; 216 | 5FAA983A21818CAC00333DE8 /* KTLoginModuleCategory */ = { 217 | isa = PBXGroup; 218 | children = ( 219 | 5FAA983C21818CAC00333DE8 /* KTComponentManager+LoginModule.h */, 220 | 5FAA983B21818CAC00333DE8 /* KTComponentManager+LoginModule.m */, 221 | ); 222 | path = KTLoginModuleCategory; 223 | sourceTree = ""; 224 | }; 225 | 5FAA98472181933600333DE8 /* KTHomeModule */ = { 226 | isa = PBXGroup; 227 | children = ( 228 | 5FAA98482181BF6200333DE8 /* Controllers */, 229 | 5FAA984C2181BF6200333DE8 /* Models */, 230 | 5FAA984B2181BF6200333DE8 /* Views */, 231 | ); 232 | path = KTHomeModule; 233 | sourceTree = ""; 234 | }; 235 | 5FAA98482181BF6200333DE8 /* Controllers */ = { 236 | isa = PBXGroup; 237 | children = ( 238 | 5FAA984A2181BF6200333DE8 /* ViewController.h */, 239 | 5FAA98492181BF6200333DE8 /* ViewController.m */, 240 | ); 241 | path = Controllers; 242 | sourceTree = ""; 243 | }; 244 | 5FAA984B2181BF6200333DE8 /* Views */ = { 245 | isa = PBXGroup; 246 | children = ( 247 | ); 248 | path = Views; 249 | sourceTree = ""; 250 | }; 251 | 5FAA984C2181BF6200333DE8 /* Models */ = { 252 | isa = PBXGroup; 253 | children = ( 254 | ); 255 | path = Models; 256 | sourceTree = ""; 257 | }; 258 | /* End PBXGroup section */ 259 | 260 | /* Begin PBXNativeTarget section */ 261 | 5FAA97D6218162F200333DE8 /* KTComponentDemo */ = { 262 | isa = PBXNativeTarget; 263 | buildConfigurationList = 5FAA9803218162F400333DE8 /* Build configuration list for PBXNativeTarget "KTComponentDemo" */; 264 | buildPhases = ( 265 | 5FAA97D3218162F200333DE8 /* Sources */, 266 | 5FAA97D4218162F200333DE8 /* Frameworks */, 267 | 5FAA97D5218162F200333DE8 /* Resources */, 268 | ); 269 | buildRules = ( 270 | ); 271 | dependencies = ( 272 | ); 273 | name = KTComponentDemo; 274 | productName = KTComponentDemo; 275 | productReference = 5FAA97D7218162F200333DE8 /* KTComponentDemo.app */; 276 | productType = "com.apple.product-type.application"; 277 | }; 278 | 5FAA97EE218162F400333DE8 /* KTComponentDemoTests */ = { 279 | isa = PBXNativeTarget; 280 | buildConfigurationList = 5FAA9806218162F400333DE8 /* Build configuration list for PBXNativeTarget "KTComponentDemoTests" */; 281 | buildPhases = ( 282 | 5FAA97EB218162F400333DE8 /* Sources */, 283 | 5FAA97EC218162F400333DE8 /* Frameworks */, 284 | 5FAA97ED218162F400333DE8 /* Resources */, 285 | ); 286 | buildRules = ( 287 | ); 288 | dependencies = ( 289 | 5FAA97F1218162F400333DE8 /* PBXTargetDependency */, 290 | ); 291 | name = KTComponentDemoTests; 292 | productName = KTComponentDemoTests; 293 | productReference = 5FAA97EF218162F400333DE8 /* KTComponentDemoTests.xctest */; 294 | productType = "com.apple.product-type.bundle.unit-test"; 295 | }; 296 | 5FAA97F9218162F400333DE8 /* KTComponentDemoUITests */ = { 297 | isa = PBXNativeTarget; 298 | buildConfigurationList = 5FAA9809218162F400333DE8 /* Build configuration list for PBXNativeTarget "KTComponentDemoUITests" */; 299 | buildPhases = ( 300 | 5FAA97F6218162F400333DE8 /* Sources */, 301 | 5FAA97F7218162F400333DE8 /* Frameworks */, 302 | 5FAA97F8218162F400333DE8 /* Resources */, 303 | ); 304 | buildRules = ( 305 | ); 306 | dependencies = ( 307 | 5FAA97FC218162F400333DE8 /* PBXTargetDependency */, 308 | ); 309 | name = KTComponentDemoUITests; 310 | productName = KTComponentDemoUITests; 311 | productReference = 5FAA97FA218162F400333DE8 /* KTComponentDemoUITests.xctest */; 312 | productType = "com.apple.product-type.bundle.ui-testing"; 313 | }; 314 | /* End PBXNativeTarget section */ 315 | 316 | /* Begin PBXProject section */ 317 | 5FAA97CF218162F200333DE8 /* Project object */ = { 318 | isa = PBXProject; 319 | attributes = { 320 | LastUpgradeCheck = 1000; 321 | ORGANIZATIONNAME = kirito_song; 322 | TargetAttributes = { 323 | 5FAA97D6218162F200333DE8 = { 324 | CreatedOnToolsVersion = 10.0; 325 | }; 326 | 5FAA97EE218162F400333DE8 = { 327 | CreatedOnToolsVersion = 10.0; 328 | TestTargetID = 5FAA97D6218162F200333DE8; 329 | }; 330 | 5FAA97F9218162F400333DE8 = { 331 | CreatedOnToolsVersion = 10.0; 332 | TestTargetID = 5FAA97D6218162F200333DE8; 333 | }; 334 | }; 335 | }; 336 | buildConfigurationList = 5FAA97D2218162F200333DE8 /* Build configuration list for PBXProject "KTComponentDemo" */; 337 | compatibilityVersion = "Xcode 9.3"; 338 | developmentRegion = en; 339 | hasScannedForEncodings = 0; 340 | knownRegions = ( 341 | en, 342 | Base, 343 | ); 344 | mainGroup = 5FAA97CE218162F200333DE8; 345 | productRefGroup = 5FAA97D8218162F200333DE8 /* Products */; 346 | projectDirPath = ""; 347 | projectRoot = ""; 348 | targets = ( 349 | 5FAA97D6218162F200333DE8 /* KTComponentDemo */, 350 | 5FAA97EE218162F400333DE8 /* KTComponentDemoTests */, 351 | 5FAA97F9218162F400333DE8 /* KTComponentDemoUITests */, 352 | ); 353 | }; 354 | /* End PBXProject section */ 355 | 356 | /* Begin PBXResourcesBuildPhase section */ 357 | 5FAA97D5218162F200333DE8 /* Resources */ = { 358 | isa = PBXResourcesBuildPhase; 359 | buildActionMask = 2147483647; 360 | files = ( 361 | 5FAA97E7218162F400333DE8 /* LaunchScreen.storyboard in Resources */, 362 | 5FAA98462181900C00333DE8 /* KTLoginViewController.xib in Resources */, 363 | 5FAA97E4218162F400333DE8 /* Assets.xcassets in Resources */, 364 | 5FAA97E2218162F200333DE8 /* Main.storyboard in Resources */, 365 | ); 366 | runOnlyForDeploymentPostprocessing = 0; 367 | }; 368 | 5FAA97ED218162F400333DE8 /* Resources */ = { 369 | isa = PBXResourcesBuildPhase; 370 | buildActionMask = 2147483647; 371 | files = ( 372 | ); 373 | runOnlyForDeploymentPostprocessing = 0; 374 | }; 375 | 5FAA97F8218162F400333DE8 /* Resources */ = { 376 | isa = PBXResourcesBuildPhase; 377 | buildActionMask = 2147483647; 378 | files = ( 379 | ); 380 | runOnlyForDeploymentPostprocessing = 0; 381 | }; 382 | /* End PBXResourcesBuildPhase section */ 383 | 384 | /* Begin PBXSourcesBuildPhase section */ 385 | 5FAA97D3218162F200333DE8 /* Sources */ = { 386 | isa = PBXSourcesBuildPhase; 387 | buildActionMask = 2147483647; 388 | files = ( 389 | 5FAA98152181651000333DE8 /* KTComponentManager.m in Sources */, 390 | 5FAA982E21818C4700333DE8 /* ModuleHandlerForLogin.m in Sources */, 391 | 5FAA98452181900C00333DE8 /* KTLoginViewController.m in Sources */, 392 | 5FAA983521818C5700333DE8 /* KTAModuleUserViewController.m in Sources */, 393 | 5FAA97EA218162F400333DE8 /* main.m in Sources */, 394 | 5FAA984D2181BF6200333DE8 /* ViewController.m in Sources */, 395 | 5FAA97DC218162F200333DE8 /* AppDelegate.m in Sources */, 396 | 5FAA983D21818CAD00333DE8 /* KTComponentManager+AModule.m in Sources */, 397 | 5FAA983621818C5700333DE8 /* KTModuleHandlerForA.m in Sources */, 398 | 5FAA983E21818CAD00333DE8 /* KTComponentManager+LoginModule.m in Sources */, 399 | 5FAA982F21818C4700333DE8 /* KTLoginManager.m in Sources */, 400 | ); 401 | runOnlyForDeploymentPostprocessing = 0; 402 | }; 403 | 5FAA97EB218162F400333DE8 /* Sources */ = { 404 | isa = PBXSourcesBuildPhase; 405 | buildActionMask = 2147483647; 406 | files = ( 407 | 5FAA97F4218162F400333DE8 /* KTComponentDemoTests.m in Sources */, 408 | ); 409 | runOnlyForDeploymentPostprocessing = 0; 410 | }; 411 | 5FAA97F6218162F400333DE8 /* Sources */ = { 412 | isa = PBXSourcesBuildPhase; 413 | buildActionMask = 2147483647; 414 | files = ( 415 | 5FAA97FF218162F400333DE8 /* KTComponentDemoUITests.m in Sources */, 416 | ); 417 | runOnlyForDeploymentPostprocessing = 0; 418 | }; 419 | /* End PBXSourcesBuildPhase section */ 420 | 421 | /* Begin PBXTargetDependency section */ 422 | 5FAA97F1218162F400333DE8 /* PBXTargetDependency */ = { 423 | isa = PBXTargetDependency; 424 | target = 5FAA97D6218162F200333DE8 /* KTComponentDemo */; 425 | targetProxy = 5FAA97F0218162F400333DE8 /* PBXContainerItemProxy */; 426 | }; 427 | 5FAA97FC218162F400333DE8 /* PBXTargetDependency */ = { 428 | isa = PBXTargetDependency; 429 | target = 5FAA97D6218162F200333DE8 /* KTComponentDemo */; 430 | targetProxy = 5FAA97FB218162F400333DE8 /* PBXContainerItemProxy */; 431 | }; 432 | /* End PBXTargetDependency section */ 433 | 434 | /* Begin PBXVariantGroup section */ 435 | 5FAA97E0218162F200333DE8 /* Main.storyboard */ = { 436 | isa = PBXVariantGroup; 437 | children = ( 438 | 5FAA97E1218162F200333DE8 /* Base */, 439 | ); 440 | name = Main.storyboard; 441 | sourceTree = ""; 442 | }; 443 | 5FAA97E5218162F400333DE8 /* LaunchScreen.storyboard */ = { 444 | isa = PBXVariantGroup; 445 | children = ( 446 | 5FAA97E6218162F400333DE8 /* Base */, 447 | ); 448 | name = LaunchScreen.storyboard; 449 | sourceTree = ""; 450 | }; 451 | /* End PBXVariantGroup section */ 452 | 453 | /* Begin XCBuildConfiguration section */ 454 | 5FAA9801218162F400333DE8 /* Debug */ = { 455 | isa = XCBuildConfiguration; 456 | buildSettings = { 457 | ALWAYS_SEARCH_USER_PATHS = NO; 458 | CLANG_ANALYZER_NONNULL = YES; 459 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 460 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 461 | CLANG_CXX_LIBRARY = "libc++"; 462 | CLANG_ENABLE_MODULES = YES; 463 | CLANG_ENABLE_OBJC_ARC = YES; 464 | CLANG_ENABLE_OBJC_WEAK = YES; 465 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 466 | CLANG_WARN_BOOL_CONVERSION = YES; 467 | CLANG_WARN_COMMA = YES; 468 | CLANG_WARN_CONSTANT_CONVERSION = YES; 469 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 470 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 471 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 472 | CLANG_WARN_EMPTY_BODY = YES; 473 | CLANG_WARN_ENUM_CONVERSION = YES; 474 | CLANG_WARN_INFINITE_RECURSION = YES; 475 | CLANG_WARN_INT_CONVERSION = YES; 476 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 477 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 478 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 479 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 480 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 481 | CLANG_WARN_STRICT_PROTOTYPES = YES; 482 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 483 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 484 | CLANG_WARN_UNREACHABLE_CODE = YES; 485 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 486 | CODE_SIGN_IDENTITY = "iPhone Developer"; 487 | COPY_PHASE_STRIP = NO; 488 | DEBUG_INFORMATION_FORMAT = dwarf; 489 | ENABLE_STRICT_OBJC_MSGSEND = YES; 490 | ENABLE_TESTABILITY = YES; 491 | GCC_C_LANGUAGE_STANDARD = gnu11; 492 | GCC_DYNAMIC_NO_PIC = NO; 493 | GCC_NO_COMMON_BLOCKS = YES; 494 | GCC_OPTIMIZATION_LEVEL = 0; 495 | GCC_PREPROCESSOR_DEFINITIONS = ( 496 | "DEBUG=1", 497 | "$(inherited)", 498 | ); 499 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 500 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 501 | GCC_WARN_UNDECLARED_SELECTOR = YES; 502 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 503 | GCC_WARN_UNUSED_FUNCTION = YES; 504 | GCC_WARN_UNUSED_VARIABLE = YES; 505 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 506 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 507 | MTL_FAST_MATH = YES; 508 | ONLY_ACTIVE_ARCH = YES; 509 | SDKROOT = iphoneos; 510 | }; 511 | name = Debug; 512 | }; 513 | 5FAA9802218162F400333DE8 /* Release */ = { 514 | isa = XCBuildConfiguration; 515 | buildSettings = { 516 | ALWAYS_SEARCH_USER_PATHS = NO; 517 | CLANG_ANALYZER_NONNULL = YES; 518 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 519 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 520 | CLANG_CXX_LIBRARY = "libc++"; 521 | CLANG_ENABLE_MODULES = YES; 522 | CLANG_ENABLE_OBJC_ARC = YES; 523 | CLANG_ENABLE_OBJC_WEAK = YES; 524 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 525 | CLANG_WARN_BOOL_CONVERSION = YES; 526 | CLANG_WARN_COMMA = YES; 527 | CLANG_WARN_CONSTANT_CONVERSION = YES; 528 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 529 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 530 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 531 | CLANG_WARN_EMPTY_BODY = YES; 532 | CLANG_WARN_ENUM_CONVERSION = YES; 533 | CLANG_WARN_INFINITE_RECURSION = YES; 534 | CLANG_WARN_INT_CONVERSION = YES; 535 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 536 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 537 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 538 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 539 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 540 | CLANG_WARN_STRICT_PROTOTYPES = YES; 541 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 542 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 543 | CLANG_WARN_UNREACHABLE_CODE = YES; 544 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 545 | CODE_SIGN_IDENTITY = "iPhone Developer"; 546 | COPY_PHASE_STRIP = NO; 547 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 548 | ENABLE_NS_ASSERTIONS = NO; 549 | ENABLE_STRICT_OBJC_MSGSEND = YES; 550 | GCC_C_LANGUAGE_STANDARD = gnu11; 551 | GCC_NO_COMMON_BLOCKS = YES; 552 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 553 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 554 | GCC_WARN_UNDECLARED_SELECTOR = YES; 555 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 556 | GCC_WARN_UNUSED_FUNCTION = YES; 557 | GCC_WARN_UNUSED_VARIABLE = YES; 558 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 559 | MTL_ENABLE_DEBUG_INFO = NO; 560 | MTL_FAST_MATH = YES; 561 | SDKROOT = iphoneos; 562 | VALIDATE_PRODUCT = YES; 563 | }; 564 | name = Release; 565 | }; 566 | 5FAA9804218162F400333DE8 /* Debug */ = { 567 | isa = XCBuildConfiguration; 568 | buildSettings = { 569 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 570 | CODE_SIGN_STYLE = Automatic; 571 | DEVELOPMENT_TEAM = QWDT94UJRT; 572 | INFOPLIST_FILE = KTComponentDemo/Info.plist; 573 | LD_RUNPATH_SEARCH_PATHS = ( 574 | "$(inherited)", 575 | "@executable_path/Frameworks", 576 | ); 577 | PRODUCT_BUNDLE_IDENTIFIER = "kirito-song.KTComponentDemo"; 578 | PRODUCT_NAME = "$(TARGET_NAME)"; 579 | TARGETED_DEVICE_FAMILY = "1,2"; 580 | }; 581 | name = Debug; 582 | }; 583 | 5FAA9805218162F400333DE8 /* Release */ = { 584 | isa = XCBuildConfiguration; 585 | buildSettings = { 586 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 587 | CODE_SIGN_STYLE = Automatic; 588 | DEVELOPMENT_TEAM = QWDT94UJRT; 589 | INFOPLIST_FILE = KTComponentDemo/Info.plist; 590 | LD_RUNPATH_SEARCH_PATHS = ( 591 | "$(inherited)", 592 | "@executable_path/Frameworks", 593 | ); 594 | PRODUCT_BUNDLE_IDENTIFIER = "kirito-song.KTComponentDemo"; 595 | PRODUCT_NAME = "$(TARGET_NAME)"; 596 | TARGETED_DEVICE_FAMILY = "1,2"; 597 | }; 598 | name = Release; 599 | }; 600 | 5FAA9807218162F400333DE8 /* Debug */ = { 601 | isa = XCBuildConfiguration; 602 | buildSettings = { 603 | BUNDLE_LOADER = "$(TEST_HOST)"; 604 | CODE_SIGN_STYLE = Automatic; 605 | DEVELOPMENT_TEAM = QWDT94UJRT; 606 | INFOPLIST_FILE = KTComponentDemoTests/Info.plist; 607 | LD_RUNPATH_SEARCH_PATHS = ( 608 | "$(inherited)", 609 | "@executable_path/Frameworks", 610 | "@loader_path/Frameworks", 611 | ); 612 | PRODUCT_BUNDLE_IDENTIFIER = "kirito-song.KTComponentDemoTests"; 613 | PRODUCT_NAME = "$(TARGET_NAME)"; 614 | TARGETED_DEVICE_FAMILY = "1,2"; 615 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/KTComponentDemo.app/KTComponentDemo"; 616 | }; 617 | name = Debug; 618 | }; 619 | 5FAA9808218162F400333DE8 /* Release */ = { 620 | isa = XCBuildConfiguration; 621 | buildSettings = { 622 | BUNDLE_LOADER = "$(TEST_HOST)"; 623 | CODE_SIGN_STYLE = Automatic; 624 | DEVELOPMENT_TEAM = QWDT94UJRT; 625 | INFOPLIST_FILE = KTComponentDemoTests/Info.plist; 626 | LD_RUNPATH_SEARCH_PATHS = ( 627 | "$(inherited)", 628 | "@executable_path/Frameworks", 629 | "@loader_path/Frameworks", 630 | ); 631 | PRODUCT_BUNDLE_IDENTIFIER = "kirito-song.KTComponentDemoTests"; 632 | PRODUCT_NAME = "$(TARGET_NAME)"; 633 | TARGETED_DEVICE_FAMILY = "1,2"; 634 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/KTComponentDemo.app/KTComponentDemo"; 635 | }; 636 | name = Release; 637 | }; 638 | 5FAA980A218162F400333DE8 /* Debug */ = { 639 | isa = XCBuildConfiguration; 640 | buildSettings = { 641 | CODE_SIGN_STYLE = Automatic; 642 | DEVELOPMENT_TEAM = QWDT94UJRT; 643 | INFOPLIST_FILE = KTComponentDemoUITests/Info.plist; 644 | LD_RUNPATH_SEARCH_PATHS = ( 645 | "$(inherited)", 646 | "@executable_path/Frameworks", 647 | "@loader_path/Frameworks", 648 | ); 649 | PRODUCT_BUNDLE_IDENTIFIER = "kirito-song.KTComponentDemoUITests"; 650 | PRODUCT_NAME = "$(TARGET_NAME)"; 651 | TARGETED_DEVICE_FAMILY = "1,2"; 652 | TEST_TARGET_NAME = KTComponentDemo; 653 | }; 654 | name = Debug; 655 | }; 656 | 5FAA980B218162F400333DE8 /* Release */ = { 657 | isa = XCBuildConfiguration; 658 | buildSettings = { 659 | CODE_SIGN_STYLE = Automatic; 660 | DEVELOPMENT_TEAM = QWDT94UJRT; 661 | INFOPLIST_FILE = KTComponentDemoUITests/Info.plist; 662 | LD_RUNPATH_SEARCH_PATHS = ( 663 | "$(inherited)", 664 | "@executable_path/Frameworks", 665 | "@loader_path/Frameworks", 666 | ); 667 | PRODUCT_BUNDLE_IDENTIFIER = "kirito-song.KTComponentDemoUITests"; 668 | PRODUCT_NAME = "$(TARGET_NAME)"; 669 | TARGETED_DEVICE_FAMILY = "1,2"; 670 | TEST_TARGET_NAME = KTComponentDemo; 671 | }; 672 | name = Release; 673 | }; 674 | /* End XCBuildConfiguration section */ 675 | 676 | /* Begin XCConfigurationList section */ 677 | 5FAA97D2218162F200333DE8 /* Build configuration list for PBXProject "KTComponentDemo" */ = { 678 | isa = XCConfigurationList; 679 | buildConfigurations = ( 680 | 5FAA9801218162F400333DE8 /* Debug */, 681 | 5FAA9802218162F400333DE8 /* Release */, 682 | ); 683 | defaultConfigurationIsVisible = 0; 684 | defaultConfigurationName = Release; 685 | }; 686 | 5FAA9803218162F400333DE8 /* Build configuration list for PBXNativeTarget "KTComponentDemo" */ = { 687 | isa = XCConfigurationList; 688 | buildConfigurations = ( 689 | 5FAA9804218162F400333DE8 /* Debug */, 690 | 5FAA9805218162F400333DE8 /* Release */, 691 | ); 692 | defaultConfigurationIsVisible = 0; 693 | defaultConfigurationName = Release; 694 | }; 695 | 5FAA9806218162F400333DE8 /* Build configuration list for PBXNativeTarget "KTComponentDemoTests" */ = { 696 | isa = XCConfigurationList; 697 | buildConfigurations = ( 698 | 5FAA9807218162F400333DE8 /* Debug */, 699 | 5FAA9808218162F400333DE8 /* Release */, 700 | ); 701 | defaultConfigurationIsVisible = 0; 702 | defaultConfigurationName = Release; 703 | }; 704 | 5FAA9809218162F400333DE8 /* Build configuration list for PBXNativeTarget "KTComponentDemoUITests" */ = { 705 | isa = XCConfigurationList; 706 | buildConfigurations = ( 707 | 5FAA980A218162F400333DE8 /* Debug */, 708 | 5FAA980B218162F400333DE8 /* Release */, 709 | ); 710 | defaultConfigurationIsVisible = 0; 711 | defaultConfigurationName = Release; 712 | }; 713 | /* End XCConfigurationList section */ 714 | }; 715 | rootObject = 5FAA97CF218162F200333DE8 /* Project object */; 716 | } 717 | --------------------------------------------------------------------------------