├── .gitignore ├── LICENSE ├── README.md ├── ReadmeSource ├── main.png ├── modules.png └── profile.png ├── fisherman.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist └── fisherman ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets ├── AppIcon.appiconset │ └── Contents.json └── Contents.json ├── FisherMan (容器框架) ├── FSMAppDelegate.h ├── FSMAppDelegate.m ├── FSMModProtocol.h ├── FSMServiceProtocol.h ├── FSMTransition.h ├── FisherMan.h ├── FisherMan.m ├── FisherManContext.h ├── FisherManContext.m └── Navigation │ ├── FSMNavigationController.h │ ├── FSMNavigationController.m │ ├── FSMNavigationDelegate.h │ ├── FSMNavigationDelegate.m │ ├── FSMNavigationTransition.h │ └── FSMNavigationTransition.m ├── Info.plist ├── Main ├── Modules(功能模块) │ ├── Launcher(首页模块) │ │ ├── LauncherModDelegate.h │ │ ├── LauncherModDelegate.m │ │ ├── LauncherModRootViewController.h │ │ └── LauncherModRootViewController.m │ └── Trade(订单模块) │ │ ├── TradeModDelegate.h │ │ ├── TradeModDelegate.m │ │ ├── TradeModRootViewController.h │ │ └── TradeModRootViewController.m └── Services(通用服务) │ └── LoginService(登录服务) │ ├── LoginService.h │ ├── LoginServiceImp.h │ └── LoginServiceImp.m ├── MyAppProfile.plist └── main.m /.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/**/*.png 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 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FisherMan 2 | 3 | ### 架构概览 4 | 5 | ![FisherMan](https://raw.githubusercontent.com/Geforceyu/FisherMan/master/ReadmeSource/main.png) 6 | 7 | 8 | **此架构的核心思想是,将经典的基于整个APP维度的AppDelegate、RootViewController缩小为模块维度,即整个项目由多个模块组合而成,每个模块都有自己的ModDelegate、ModRootViewController,由一个全局的容器来包含这些模块,APP的生命周期也交由这个全局容器处理,容器再将APP事件分发到各个模块。所有模块和服务只依赖此容器,模块间互不依赖** 9 | 10 | ![](https://raw.githubusercontent.com/Geforceyu/FisherMan/master/ReadmeSource/modules.png) 11 | 12 | ### 面向协议 13 | >此架构主要利用OC的协议,来达到约束模块和服务的目的,同时协议也使得架构更加灵活、有效减少耦合和强依赖。以下两个协议即此架构的核心协议 14 | 15 | 1. **FSMModProtocol**
16 | *所有模块的代理者都需要遵守此协议,以统一模块与容器的交互一致性,以及接收app的生命周期事件。* 17 | ```Objective-C 18 | @protocol FSMModProtocol 19 | 20 | @required 21 | //返回当前模块的根视图控制器 22 | - (UIViewController *)rootViewControllerForMod; 23 | 24 | @optional 25 | 26 | - (void)modDidFinishLaunchingWithOptions:(NSDictionary *)options; 27 | 28 | - (void)modWillResignActive; 29 | 30 | - (void)modDidEnterBackground; 31 | 32 | - (void)modWillEnterForeground; 33 | 34 | - (void)modDidBecomeActive; 35 | 36 | - (void)modWillTerminate; 37 | 38 | - (void)modDidReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler; 39 | 40 | @end 41 | ``` 42 | 43 | 2. **FSMServiceProtol**
44 | *所有服务协议的根协议,主要定义了服务的生命周期事件,统一服务模型,以便于各服务提供者在各个生命周期做数据初始化或逻辑处理等* 45 | 46 | 47 | ----------------------------- 48 | ### 核心方法 49 | 50 | - 模块间的跳转 51 | ```Objective-C 52 | //启动订单模块 53 | [[FisherMan man] launchModuleWithName:@"TradeMod" parameters:nil transition:FMModTransitionTypePush]; 54 | ``` 55 | 56 | - 服务的调用 57 | ```Objective-C 58 | //定义登录服务所能提供的服务 59 | @protocol LoginService 60 | 61 | - (void)loginWithUserName:(NSString *)userName passwd:(NSString *)passwd; 62 | 63 | - (NSString *)loginUserName; 64 | 65 | @end 66 | 67 | //调用登录服务 68 | id loginService = [[FisherMan man] findServiceWithName:@"LoginService"]; 69 | [loginService loginWithUserName:@"xiaowang" passwd:@"123"]; 70 | ``` 71 | >服务的调用方和提供方不直接依赖,而是通过中间者和虚拟的服务协议,若以后服务提供方需要更换,调用方代码无需变动,易于切换 72 | 73 | 74 | 75 | ### 注册 76 | 77 | > 采用plist来保存模块和服务的注册信息 78 | 79 | ![](https://raw.githubusercontent.com/Geforceyu/FisherMan/master/ReadmeSource/profile.png) 80 | 81 | > tip:这里services和modules的信息放在一个plist文件里面,若项目过大,可考虑将services和modules的注册plist文件拆成两个分别存放。 82 | - 每个服务的信息包括服务名(name)及服务的实现类名(imp)组成。 83 | - 每个模块的信息包括模块的名(name)及模块的代理者类名(delegate)组成。 84 | 85 | ### 大致流程 86 | 1. APP启动后初始化FisherContext,指定plist等 87 | 2. FisherMan读取plist文件,获取模块和服务的注册信息 88 | 2. 启动注册的服务,并记录运行中的服务 89 | 3. 创建注册表中第一个模块的代理者,询问代理者以获取第一个模块的根视图控制器,作为app启动的第一个界面 90 | 4. 模块中调用服务时,通过FisherMan和`服务名`查找对应服务,FisherMan通过服务注册信息找到实际服务提供者 91 | 5. 启动其它模块时,通过FiserMan和`模块名`来启动并跳转,FisherMan通过模块注册信息,找到模块的代理者,并向模块代理者询问此模块的根视图控制器以跳转到此视图控制器。 92 | 93 | -------------------------- 94 | #### 详细内容请下载代码查看 95 | -------------------------- 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /ReadmeSource/main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Geforceyu/FisherMan/f18fad2e2a6172527c01a5e8b688417b4f2e52e4/ReadmeSource/main.png -------------------------------------------------------------------------------- /ReadmeSource/modules.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Geforceyu/FisherMan/f18fad2e2a6172527c01a5e8b688417b4f2e52e4/ReadmeSource/modules.png -------------------------------------------------------------------------------- /ReadmeSource/profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Geforceyu/FisherMan/f18fad2e2a6172527c01a5e8b688417b4f2e52e4/ReadmeSource/profile.png -------------------------------------------------------------------------------- /fisherman.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | AD145734219424BB0009F9EC /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AD145733219424BB0009F9EC /* AppDelegate.m */; }; 11 | AD14573C219424BD0009F9EC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AD14573B219424BD0009F9EC /* Assets.xcassets */; }; 12 | AD145742219424BD0009F9EC /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = AD145741219424BD0009F9EC /* main.m */; }; 13 | AD14574F219427250009F9EC /* FisherMan.m in Sources */ = {isa = PBXBuildFile; fileRef = AD14574E219427250009F9EC /* FisherMan.m */; }; 14 | AD1457592194289F0009F9EC /* LauncherModDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AD1457582194289F0009F9EC /* LauncherModDelegate.m */; }; 15 | AD14575C219428B30009F9EC /* LauncherModRootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AD14575B219428B30009F9EC /* LauncherModRootViewController.m */; }; 16 | AD1457632194303D0009F9EC /* FSMAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AD1457622194303D0009F9EC /* FSMAppDelegate.m */; }; 17 | AD145769219434000009F9EC /* TradeModRootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AD145768219434000009F9EC /* TradeModRootViewController.m */; }; 18 | AD14576C219434260009F9EC /* TradeModDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AD14576B219434260009F9EC /* TradeModDelegate.m */; }; 19 | ADB8E57C219A9C8700427324 /* LoginServiceImp.m in Sources */ = {isa = PBXBuildFile; fileRef = ADB8E57A219A9C8700427324 /* LoginServiceImp.m */; }; 20 | ADCEB8AD224B74A6003B1961 /* FisherManContext.m in Sources */ = {isa = PBXBuildFile; fileRef = ADCEB8AC224B74A6003B1961 /* FisherManContext.m */; }; 21 | ADCEB8AF224B775E003B1961 /* MyAppProfile.plist in Resources */ = {isa = PBXBuildFile; fileRef = ADCEB8AE224B775E003B1961 /* MyAppProfile.plist */; }; 22 | ADCEB8BA224B8330003B1961 /* FSMNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = ADCEB8B9224B8330003B1961 /* FSMNavigationController.m */; }; 23 | ADCEB8BD224B834D003B1961 /* FSMNavigationDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = ADCEB8BC224B834D003B1961 /* FSMNavigationDelegate.m */; }; 24 | ADCEB8C0224B8364003B1961 /* FSMNavigationTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = ADCEB8BF224B8364003B1961 /* FSMNavigationTransition.m */; }; 25 | /* End PBXBuildFile section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | AD14572F219424BB0009F9EC /* fisherman.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = fisherman.app; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | AD145732219424BB0009F9EC /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 30 | AD145733219424BB0009F9EC /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 31 | AD14573B219424BD0009F9EC /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 32 | AD145740219424BD0009F9EC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 33 | AD145741219424BD0009F9EC /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 34 | AD14574D219427250009F9EC /* FisherMan.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FisherMan.h; sourceTree = ""; }; 35 | AD14574E219427250009F9EC /* FisherMan.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FisherMan.m; sourceTree = ""; }; 36 | AD145750219427C30009F9EC /* FSMModProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FSMModProtocol.h; sourceTree = ""; }; 37 | AD145751219427D70009F9EC /* FSMServiceProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FSMServiceProtocol.h; sourceTree = ""; }; 38 | AD1457572194289F0009F9EC /* LauncherModDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LauncherModDelegate.h; sourceTree = ""; }; 39 | AD1457582194289F0009F9EC /* LauncherModDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LauncherModDelegate.m; sourceTree = ""; }; 40 | AD14575A219428B30009F9EC /* LauncherModRootViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LauncherModRootViewController.h; sourceTree = ""; }; 41 | AD14575B219428B30009F9EC /* LauncherModRootViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LauncherModRootViewController.m; sourceTree = ""; }; 42 | AD1457612194303D0009F9EC /* FSMAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FSMAppDelegate.h; sourceTree = ""; }; 43 | AD1457622194303D0009F9EC /* FSMAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FSMAppDelegate.m; sourceTree = ""; }; 44 | AD145767219434000009F9EC /* TradeModRootViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TradeModRootViewController.h; sourceTree = ""; }; 45 | AD145768219434000009F9EC /* TradeModRootViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TradeModRootViewController.m; sourceTree = ""; }; 46 | AD14576A219434260009F9EC /* TradeModDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TradeModDelegate.h; sourceTree = ""; }; 47 | AD14576B219434260009F9EC /* TradeModDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TradeModDelegate.m; sourceTree = ""; }; 48 | ADB8E579219A9C8700427324 /* LoginServiceImp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoginServiceImp.h; sourceTree = ""; }; 49 | ADB8E57A219A9C8700427324 /* LoginServiceImp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LoginServiceImp.m; sourceTree = ""; }; 50 | ADB8E57B219A9C8700427324 /* LoginService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoginService.h; sourceTree = ""; }; 51 | ADCEB8AB224B74A6003B1961 /* FisherManContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FisherManContext.h; sourceTree = ""; }; 52 | ADCEB8AC224B74A6003B1961 /* FisherManContext.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FisherManContext.m; sourceTree = ""; }; 53 | ADCEB8AE224B775E003B1961 /* MyAppProfile.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = MyAppProfile.plist; sourceTree = ""; }; 54 | ADCEB8B8224B8330003B1961 /* FSMNavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FSMNavigationController.h; sourceTree = ""; }; 55 | ADCEB8B9224B8330003B1961 /* FSMNavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FSMNavigationController.m; sourceTree = ""; }; 56 | ADCEB8BB224B834D003B1961 /* FSMNavigationDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSMNavigationDelegate.h; sourceTree = ""; }; 57 | ADCEB8BC224B834D003B1961 /* FSMNavigationDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FSMNavigationDelegate.m; sourceTree = ""; }; 58 | ADCEB8BE224B8364003B1961 /* FSMNavigationTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FSMNavigationTransition.h; sourceTree = ""; }; 59 | ADCEB8BF224B8364003B1961 /* FSMNavigationTransition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FSMNavigationTransition.m; sourceTree = ""; }; 60 | /* End PBXFileReference section */ 61 | 62 | /* Begin PBXFrameworksBuildPhase section */ 63 | AD14572C219424BB0009F9EC /* Frameworks */ = { 64 | isa = PBXFrameworksBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | ); 68 | runOnlyForDeploymentPostprocessing = 0; 69 | }; 70 | /* End PBXFrameworksBuildPhase section */ 71 | 72 | /* Begin PBXGroup section */ 73 | AD145726219424BB0009F9EC = { 74 | isa = PBXGroup; 75 | children = ( 76 | AD145731219424BB0009F9EC /* fisherman */, 77 | AD145730219424BB0009F9EC /* Products */, 78 | ); 79 | sourceTree = ""; 80 | }; 81 | AD145730219424BB0009F9EC /* Products */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | AD14572F219424BB0009F9EC /* fisherman.app */, 85 | ); 86 | name = Products; 87 | sourceTree = ""; 88 | }; 89 | AD145731219424BB0009F9EC /* fisherman */ = { 90 | isa = PBXGroup; 91 | children = ( 92 | AD145732219424BB0009F9EC /* AppDelegate.h */, 93 | AD145733219424BB0009F9EC /* AppDelegate.m */, 94 | AD14573B219424BD0009F9EC /* Assets.xcassets */, 95 | AD145740219424BD0009F9EC /* Info.plist */, 96 | ADCEB8AE224B775E003B1961 /* MyAppProfile.plist */, 97 | AD145741219424BD0009F9EC /* main.m */, 98 | AD1457522194283F0009F9EC /* Main */, 99 | AD14574A219426050009F9EC /* FisherMan (容器框架) */, 100 | ); 101 | path = fisherman; 102 | sourceTree = ""; 103 | }; 104 | AD14574A219426050009F9EC /* FisherMan (容器框架) */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | ADCEB8AB224B74A6003B1961 /* FisherManContext.h */, 108 | ADCEB8AC224B74A6003B1961 /* FisherManContext.m */, 109 | AD14574D219427250009F9EC /* FisherMan.h */, 110 | AD14574E219427250009F9EC /* FisherMan.m */, 111 | AD1457612194303D0009F9EC /* FSMAppDelegate.h */, 112 | AD1457622194303D0009F9EC /* FSMAppDelegate.m */, 113 | AD145750219427C30009F9EC /* FSMModProtocol.h */, 114 | AD145751219427D70009F9EC /* FSMServiceProtocol.h */, 115 | ADCEB8B7224B8310003B1961 /* Navigation */, 116 | ); 117 | path = "FisherMan (容器框架)"; 118 | sourceTree = ""; 119 | }; 120 | AD1457522194283F0009F9EC /* Main */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | AD1457532194283F0009F9EC /* Modules(功能模块) */, 124 | AD1457542194283F0009F9EC /* Services(通用服务) */, 125 | ); 126 | path = Main; 127 | sourceTree = ""; 128 | }; 129 | AD1457532194283F0009F9EC /* Modules(功能模块) */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | AD1457552194285B0009F9EC /* Launcher(首页模块) */, 133 | AD1457562194285B0009F9EC /* Trade(订单模块) */, 134 | ); 135 | path = "Modules(功能模块)"; 136 | sourceTree = ""; 137 | }; 138 | AD1457542194283F0009F9EC /* Services(通用服务) */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | ADB8E578219A9C8700427324 /* LoginService(登录服务) */, 142 | ); 143 | path = "Services(通用服务)"; 144 | sourceTree = ""; 145 | }; 146 | AD1457552194285B0009F9EC /* Launcher(首页模块) */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | AD1457572194289F0009F9EC /* LauncherModDelegate.h */, 150 | AD1457582194289F0009F9EC /* LauncherModDelegate.m */, 151 | AD14575A219428B30009F9EC /* LauncherModRootViewController.h */, 152 | AD14575B219428B30009F9EC /* LauncherModRootViewController.m */, 153 | ); 154 | path = "Launcher(首页模块)"; 155 | sourceTree = ""; 156 | }; 157 | AD1457562194285B0009F9EC /* Trade(订单模块) */ = { 158 | isa = PBXGroup; 159 | children = ( 160 | AD14576A219434260009F9EC /* TradeModDelegate.h */, 161 | AD14576B219434260009F9EC /* TradeModDelegate.m */, 162 | AD145767219434000009F9EC /* TradeModRootViewController.h */, 163 | AD145768219434000009F9EC /* TradeModRootViewController.m */, 164 | ); 165 | path = "Trade(订单模块)"; 166 | sourceTree = ""; 167 | }; 168 | ADB8E578219A9C8700427324 /* LoginService(登录服务) */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | ADB8E579219A9C8700427324 /* LoginServiceImp.h */, 172 | ADB8E57A219A9C8700427324 /* LoginServiceImp.m */, 173 | ADB8E57B219A9C8700427324 /* LoginService.h */, 174 | ); 175 | path = "LoginService(登录服务)"; 176 | sourceTree = ""; 177 | }; 178 | ADCEB8B7224B8310003B1961 /* Navigation */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | ADCEB8B8224B8330003B1961 /* FSMNavigationController.h */, 182 | ADCEB8B9224B8330003B1961 /* FSMNavigationController.m */, 183 | ADCEB8BB224B834D003B1961 /* FSMNavigationDelegate.h */, 184 | ADCEB8BC224B834D003B1961 /* FSMNavigationDelegate.m */, 185 | ADCEB8BE224B8364003B1961 /* FSMNavigationTransition.h */, 186 | ADCEB8BF224B8364003B1961 /* FSMNavigationTransition.m */, 187 | ); 188 | path = Navigation; 189 | sourceTree = ""; 190 | }; 191 | /* End PBXGroup section */ 192 | 193 | /* Begin PBXNativeTarget section */ 194 | AD14572E219424BB0009F9EC /* fisherman */ = { 195 | isa = PBXNativeTarget; 196 | buildConfigurationList = AD145745219424BD0009F9EC /* Build configuration list for PBXNativeTarget "fisherman" */; 197 | buildPhases = ( 198 | AD14572B219424BB0009F9EC /* Sources */, 199 | AD14572C219424BB0009F9EC /* Frameworks */, 200 | AD14572D219424BB0009F9EC /* Resources */, 201 | ); 202 | buildRules = ( 203 | ); 204 | dependencies = ( 205 | ); 206 | name = fisherman; 207 | productName = fisherman; 208 | productReference = AD14572F219424BB0009F9EC /* fisherman.app */; 209 | productType = "com.apple.product-type.application"; 210 | }; 211 | /* End PBXNativeTarget section */ 212 | 213 | /* Begin PBXProject section */ 214 | AD145727219424BB0009F9EC /* Project object */ = { 215 | isa = PBXProject; 216 | attributes = { 217 | LastUpgradeCheck = 1010; 218 | ORGANIZATIONNAME = keruyun; 219 | TargetAttributes = { 220 | AD14572E219424BB0009F9EC = { 221 | CreatedOnToolsVersion = 10.1; 222 | }; 223 | }; 224 | }; 225 | buildConfigurationList = AD14572A219424BB0009F9EC /* Build configuration list for PBXProject "fisherman" */; 226 | compatibilityVersion = "Xcode 9.3"; 227 | developmentRegion = en; 228 | hasScannedForEncodings = 0; 229 | knownRegions = ( 230 | en, 231 | Base, 232 | ); 233 | mainGroup = AD145726219424BB0009F9EC; 234 | productRefGroup = AD145730219424BB0009F9EC /* Products */; 235 | projectDirPath = ""; 236 | projectRoot = ""; 237 | targets = ( 238 | AD14572E219424BB0009F9EC /* fisherman */, 239 | ); 240 | }; 241 | /* End PBXProject section */ 242 | 243 | /* Begin PBXResourcesBuildPhase section */ 244 | AD14572D219424BB0009F9EC /* Resources */ = { 245 | isa = PBXResourcesBuildPhase; 246 | buildActionMask = 2147483647; 247 | files = ( 248 | ADCEB8AF224B775E003B1961 /* MyAppProfile.plist in Resources */, 249 | AD14573C219424BD0009F9EC /* Assets.xcassets in Resources */, 250 | ); 251 | runOnlyForDeploymentPostprocessing = 0; 252 | }; 253 | /* End PBXResourcesBuildPhase section */ 254 | 255 | /* Begin PBXSourcesBuildPhase section */ 256 | AD14572B219424BB0009F9EC /* Sources */ = { 257 | isa = PBXSourcesBuildPhase; 258 | buildActionMask = 2147483647; 259 | files = ( 260 | ADCEB8BD224B834D003B1961 /* FSMNavigationDelegate.m in Sources */, 261 | AD145769219434000009F9EC /* TradeModRootViewController.m in Sources */, 262 | AD14575C219428B30009F9EC /* LauncherModRootViewController.m in Sources */, 263 | ADCEB8BA224B8330003B1961 /* FSMNavigationController.m in Sources */, 264 | AD1457592194289F0009F9EC /* LauncherModDelegate.m in Sources */, 265 | AD145742219424BD0009F9EC /* main.m in Sources */, 266 | AD14576C219434260009F9EC /* TradeModDelegate.m in Sources */, 267 | ADCEB8C0224B8364003B1961 /* FSMNavigationTransition.m in Sources */, 268 | ADCEB8AD224B74A6003B1961 /* FisherManContext.m in Sources */, 269 | AD14574F219427250009F9EC /* FisherMan.m in Sources */, 270 | ADB8E57C219A9C8700427324 /* LoginServiceImp.m in Sources */, 271 | AD1457632194303D0009F9EC /* FSMAppDelegate.m in Sources */, 272 | AD145734219424BB0009F9EC /* AppDelegate.m in Sources */, 273 | ); 274 | runOnlyForDeploymentPostprocessing = 0; 275 | }; 276 | /* End PBXSourcesBuildPhase section */ 277 | 278 | /* Begin XCBuildConfiguration section */ 279 | AD145743219424BD0009F9EC /* Debug */ = { 280 | isa = XCBuildConfiguration; 281 | buildSettings = { 282 | ALWAYS_SEARCH_USER_PATHS = NO; 283 | CLANG_ANALYZER_NONNULL = YES; 284 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 285 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 286 | CLANG_CXX_LIBRARY = "libc++"; 287 | CLANG_ENABLE_MODULES = YES; 288 | CLANG_ENABLE_OBJC_ARC = YES; 289 | CLANG_ENABLE_OBJC_WEAK = YES; 290 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 291 | CLANG_WARN_BOOL_CONVERSION = YES; 292 | CLANG_WARN_COMMA = YES; 293 | CLANG_WARN_CONSTANT_CONVERSION = YES; 294 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 295 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 296 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 297 | CLANG_WARN_EMPTY_BODY = YES; 298 | CLANG_WARN_ENUM_CONVERSION = YES; 299 | CLANG_WARN_INFINITE_RECURSION = YES; 300 | CLANG_WARN_INT_CONVERSION = YES; 301 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 302 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 303 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 304 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 305 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 306 | CLANG_WARN_STRICT_PROTOTYPES = YES; 307 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 308 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 309 | CLANG_WARN_UNREACHABLE_CODE = YES; 310 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 311 | CODE_SIGN_IDENTITY = "iPhone Developer"; 312 | COPY_PHASE_STRIP = NO; 313 | DEBUG_INFORMATION_FORMAT = dwarf; 314 | ENABLE_STRICT_OBJC_MSGSEND = YES; 315 | ENABLE_TESTABILITY = YES; 316 | GCC_C_LANGUAGE_STANDARD = gnu11; 317 | GCC_DYNAMIC_NO_PIC = NO; 318 | GCC_NO_COMMON_BLOCKS = YES; 319 | GCC_OPTIMIZATION_LEVEL = 0; 320 | GCC_PREPROCESSOR_DEFINITIONS = ( 321 | "DEBUG=1", 322 | "$(inherited)", 323 | ); 324 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 325 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 326 | GCC_WARN_UNDECLARED_SELECTOR = YES; 327 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 328 | GCC_WARN_UNUSED_FUNCTION = YES; 329 | GCC_WARN_UNUSED_VARIABLE = YES; 330 | IPHONEOS_DEPLOYMENT_TARGET = 12.1; 331 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 332 | MTL_FAST_MATH = YES; 333 | ONLY_ACTIVE_ARCH = YES; 334 | SDKROOT = iphoneos; 335 | }; 336 | name = Debug; 337 | }; 338 | AD145744219424BD0009F9EC /* Release */ = { 339 | isa = XCBuildConfiguration; 340 | buildSettings = { 341 | ALWAYS_SEARCH_USER_PATHS = NO; 342 | CLANG_ANALYZER_NONNULL = YES; 343 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 344 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 345 | CLANG_CXX_LIBRARY = "libc++"; 346 | CLANG_ENABLE_MODULES = YES; 347 | CLANG_ENABLE_OBJC_ARC = YES; 348 | CLANG_ENABLE_OBJC_WEAK = YES; 349 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 350 | CLANG_WARN_BOOL_CONVERSION = YES; 351 | CLANG_WARN_COMMA = YES; 352 | CLANG_WARN_CONSTANT_CONVERSION = YES; 353 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 354 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 355 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 356 | CLANG_WARN_EMPTY_BODY = YES; 357 | CLANG_WARN_ENUM_CONVERSION = YES; 358 | CLANG_WARN_INFINITE_RECURSION = YES; 359 | CLANG_WARN_INT_CONVERSION = YES; 360 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 361 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 362 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 363 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 364 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 365 | CLANG_WARN_STRICT_PROTOTYPES = YES; 366 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 367 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 368 | CLANG_WARN_UNREACHABLE_CODE = YES; 369 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 370 | CODE_SIGN_IDENTITY = "iPhone Developer"; 371 | COPY_PHASE_STRIP = NO; 372 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 373 | ENABLE_NS_ASSERTIONS = NO; 374 | ENABLE_STRICT_OBJC_MSGSEND = YES; 375 | GCC_C_LANGUAGE_STANDARD = gnu11; 376 | GCC_NO_COMMON_BLOCKS = YES; 377 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 378 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 379 | GCC_WARN_UNDECLARED_SELECTOR = YES; 380 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 381 | GCC_WARN_UNUSED_FUNCTION = YES; 382 | GCC_WARN_UNUSED_VARIABLE = YES; 383 | IPHONEOS_DEPLOYMENT_TARGET = 12.1; 384 | MTL_ENABLE_DEBUG_INFO = NO; 385 | MTL_FAST_MATH = YES; 386 | SDKROOT = iphoneos; 387 | VALIDATE_PRODUCT = YES; 388 | }; 389 | name = Release; 390 | }; 391 | AD145746219424BD0009F9EC /* Debug */ = { 392 | isa = XCBuildConfiguration; 393 | buildSettings = { 394 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 395 | CODE_SIGN_STYLE = Automatic; 396 | INFOPLIST_FILE = fisherman/Info.plist; 397 | LD_RUNPATH_SEARCH_PATHS = ( 398 | "$(inherited)", 399 | "@executable_path/Frameworks", 400 | ); 401 | PRODUCT_BUNDLE_IDENTIFIER = com.keruyun.fisherman; 402 | PRODUCT_NAME = "$(TARGET_NAME)"; 403 | TARGETED_DEVICE_FAMILY = "1,2"; 404 | }; 405 | name = Debug; 406 | }; 407 | AD145747219424BD0009F9EC /* Release */ = { 408 | isa = XCBuildConfiguration; 409 | buildSettings = { 410 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 411 | CODE_SIGN_STYLE = Automatic; 412 | INFOPLIST_FILE = fisherman/Info.plist; 413 | LD_RUNPATH_SEARCH_PATHS = ( 414 | "$(inherited)", 415 | "@executable_path/Frameworks", 416 | ); 417 | PRODUCT_BUNDLE_IDENTIFIER = com.keruyun.fisherman; 418 | PRODUCT_NAME = "$(TARGET_NAME)"; 419 | TARGETED_DEVICE_FAMILY = "1,2"; 420 | }; 421 | name = Release; 422 | }; 423 | /* End XCBuildConfiguration section */ 424 | 425 | /* Begin XCConfigurationList section */ 426 | AD14572A219424BB0009F9EC /* Build configuration list for PBXProject "fisherman" */ = { 427 | isa = XCConfigurationList; 428 | buildConfigurations = ( 429 | AD145743219424BD0009F9EC /* Debug */, 430 | AD145744219424BD0009F9EC /* Release */, 431 | ); 432 | defaultConfigurationIsVisible = 0; 433 | defaultConfigurationName = Release; 434 | }; 435 | AD145745219424BD0009F9EC /* Build configuration list for PBXNativeTarget "fisherman" */ = { 436 | isa = XCConfigurationList; 437 | buildConfigurations = ( 438 | AD145746219424BD0009F9EC /* Debug */, 439 | AD145747219424BD0009F9EC /* Release */, 440 | ); 441 | defaultConfigurationIsVisible = 0; 442 | defaultConfigurationName = Release; 443 | }; 444 | /* End XCConfigurationList section */ 445 | }; 446 | rootObject = AD145727219424BB0009F9EC /* Project object */; 447 | } 448 | -------------------------------------------------------------------------------- /fisherman.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /fisherman.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /fisherman/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FSMAppDelegate.h" 11 | 12 | @interface AppDelegate : FSMAppDelegate 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /fisherman/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "FisherManContext.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | // Override point for customization after application launch. 21 | [FisherManContext context].profileName = @"MyAppProfile"; 22 | [super application:application didFinishLaunchingWithOptions:launchOptions]; 23 | return YES; 24 | } 25 | @end 26 | -------------------------------------------------------------------------------- /fisherman/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 | } -------------------------------------------------------------------------------- /fisherman/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /fisherman/FisherMan (容器框架)/FSMAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSMAppDelegate.h 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface FSMAppDelegate : NSObject 13 | 14 | @property (nonatomic, strong) UIWindow *window; 15 | @end 16 | -------------------------------------------------------------------------------- /fisherman/FisherMan (容器框架)/FSMAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSMAppDelegate.m 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import "FSMAppDelegate.h" 10 | #import "FisherMan.h" 11 | 12 | @implementation FSMAppDelegate 13 | 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 15 | // Override point for customization after application launch. 16 | 17 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 18 | self.window.backgroundColor = [UIColor whiteColor]; 19 | self.window.rootViewController = [[FisherMan man] appRootViewController]; 20 | [self.window makeKeyAndVisible]; 21 | 22 | return YES; 23 | } 24 | 25 | 26 | - (void)applicationWillResignActive:(UIApplication *)application { 27 | 28 | } 29 | 30 | 31 | - (void)applicationDidEnterBackground:(UIApplication *)application { 32 | 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | 48 | } 49 | - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler 50 | { 51 | //无缝对接app收到推送后的跳转 52 | NSString *modName = userInfo[@"modName"]; 53 | NSDictionary *modParameters = userInfo[@"modParameters"]; 54 | [[FisherMan man] launchModuleWithName:modName parameters:modParameters transition:FMModTransitionTypePush]; 55 | } 56 | @end 57 | -------------------------------------------------------------------------------- /fisherman/FisherMan (容器框架)/FSMModProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // FMModAppDelegate.h 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | //所有容器内的注册的模块必须遵循的协议 13 | 14 | @protocol FSMModProtocol 15 | 16 | @required 17 | - (UIViewController *)rootViewControllerForMod; 18 | 19 | @optional 20 | 21 | - (void)modDidFinishLaunchingWithOptions:(NSDictionary *)options; 22 | 23 | - (void)modWillResignActive; 24 | 25 | - (void)modDidEnterBackground; 26 | 27 | - (void)modWillEnterForeground; 28 | 29 | - (void)modDidBecomeActive; 30 | 31 | - (void)modWillTerminate; 32 | 33 | - (void)modDidReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /fisherman/FisherMan (容器框架)/FSMServiceProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // FMService.h 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //容器内所有注册的服务遵循的根协议 12 | @protocol FSMServiceProtocol 13 | 14 | @optional 15 | 16 | - (void)serviceStart; 17 | 18 | @end 19 | 20 | -------------------------------------------------------------------------------- /fisherman/FisherMan (容器框架)/FSMTransition.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSMTransition.h 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2019/3/27. 6 | // Copyright © 2019 keruyun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface FSMNavcDelegate : NSObject 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /fisherman/FisherMan (容器框架)/FisherMan.h: -------------------------------------------------------------------------------- 1 | // 2 | // FiserMan.h 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FSMModProtocol.h" 11 | #import "FSMServiceProtocol.h" 12 | 13 | typedef enum : NSUInteger { 14 | FMModTransitionTypeNone, 15 | FMModTransitionTypePush, 16 | FMModTransitionTypePresent, 17 | } FMModTransitionType; 18 | 19 | @interface FisherMan : NSObject 20 | 21 | @property (nonatomic,strong,readonly)UIViewController *appRootViewController; 22 | 23 | + (instancetype)man; 24 | 25 | - (void)launchModuleWithName:(NSString *)moduleName parameters:(NSDictionary *)parameters transition:(FMModTransitionType)transitionType; 26 | 27 | - (void)exitCurrentModule; 28 | 29 | - (id)findServiceWithName:(NSString *)serviceName; 30 | 31 | - (void)applicationDidEnterBackground:(UIApplication *)application; 32 | 33 | @end 34 | 35 | -------------------------------------------------------------------------------- /fisherman/FisherMan (容器框架)/FisherMan.m: -------------------------------------------------------------------------------- 1 | // 2 | // FiserMan.m 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import "FisherMan.h" 10 | #import "FisherManContext.h" 11 | #import "FSMNavigationController.h" 12 | 13 | @interface FisherMan () 14 | 15 | @property (nonatomic,strong)UIViewController *appRootViewController; 16 | 17 | @end 18 | 19 | @implementation FisherMan 20 | { 21 | NSDictionary *_map; 22 | NSArray *_registerModules; 23 | NSArray *_registerServices; 24 | NSMutableArray *_runingModules; 25 | NSMutableArray *_runingServices; 26 | FMModTransitionType _lastTransitionType; 27 | FSMNavigationController *_rootVC; 28 | } 29 | 30 | + (instancetype)man 31 | { 32 | static dispatch_once_t onceToken; 33 | static FisherMan *man = nil; 34 | dispatch_once(&onceToken, ^{ 35 | man = [[FisherMan alloc] init]; 36 | }); 37 | return man; 38 | } 39 | 40 | - (instancetype)init 41 | { 42 | self = [super init]; 43 | if (self) { 44 | _runingModules = [NSMutableArray array]; 45 | _runingServices = [NSMutableArray array]; 46 | 47 | _map = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[FisherManContext context].profileName ofType:@"plist"]]; 48 | _registerModules = _map[@"Modules"]; 49 | _registerServices = _map[@"Services"]; 50 | 51 | //启动注册的服务 52 | for (NSDictionary *service in _registerServices) { 53 | Class class = NSClassFromString(service[@"imp"]); 54 | id service = [class new]; 55 | [_runingServices addObject:service]; 56 | [service serviceStart]; 57 | } 58 | } 59 | return self; 60 | } 61 | //将注册的第一个模块的根视图控制器作为app的根视图控制器 62 | - (UIViewController *)appRootViewController 63 | { 64 | Class class = NSClassFromString(_registerModules.firstObject[@"delegate"]); 65 | id module = [[class alloc] init]; 66 | [module modDidFinishLaunchingWithOptions:nil]; 67 | [_runingModules addObject:module]; 68 | UIViewController *firstModVC = [module rootViewControllerForMod]; 69 | _rootVC = [[FSMNavigationController alloc] initWithRootViewController:firstModVC]; 70 | return _rootVC; 71 | } 72 | //启动某个已注册的模块 73 | - (void)launchModuleWithName:(NSString *)moduleName parameters:(NSDictionary *)parameters transition:(FMModTransitionType)transitionType 74 | { 75 | for (NSDictionary *registerMod in _registerModules) { 76 | //遍历判断已注册的模块名 77 | if ([registerMod[@"name"] isEqualToString:moduleName]) { 78 | //创建启动模块对象 79 | Class class = NSClassFromString(registerMod[@"delegate"]); 80 | id mod = [[class alloc] init]; 81 | if (![mod conformsToProtocol:@protocol(FSMModProtocol)]) { 82 | NSLog(@"模块[%@]必须遵守FSMModProtocol协议",moduleName); 83 | return; 84 | } 85 | [mod modDidFinishLaunchingWithOptions:parameters]; 86 | [_runingModules addObject:mod]; 87 | //获取启动模块的根视图控制器 88 | UIViewController *modRootVC = [mod rootViewControllerForMod]; 89 | 90 | if (transitionType==FMModTransitionTypePush) { 91 | [_rootVC pushViewController:modRootVC animated:YES]; 92 | }else { 93 | [_rootVC pushViewController:modRootVC type:@"modal"]; 94 | } 95 | _lastTransitionType = transitionType; 96 | break; 97 | } 98 | } 99 | } 100 | //退出当前模块 101 | - (void)exitCurrentModule 102 | { 103 | if (_lastTransitionType==FMModTransitionTypePush) { 104 | [_rootVC popViewControllerAnimated:YES]; 105 | }else{ 106 | [_rootVC popViewControllerAnimated:YES]; 107 | } 108 | } 109 | //查找服务 110 | - (id)findServiceWithName:(NSString *)serviceName 111 | { 112 | BOOL registed = NO; 113 | NSString *serviceImpName = nil; 114 | for (NSDictionary *serviceDict in _registerServices) { 115 | if ([serviceDict[@"name"] isEqualToString:serviceName]) { 116 | registed = YES; 117 | serviceImpName = serviceDict[@"imp"]; 118 | break; 119 | } 120 | } 121 | if (!registed) { 122 | NSLog(@"查找的服务未注册!"); 123 | return nil; 124 | } 125 | if (!serviceImpName) { 126 | NSLog(@"服务未设置服务者!"); 127 | return nil; 128 | } 129 | for (id service in _runingServices) { 130 | if (![service conformsToProtocol:@protocol(FSMServiceProtocol)]) { 131 | NSLog(@"服务[%@]必须遵守FSMServiceProtocol协议",serviceName); 132 | return nil; 133 | } 134 | if ([NSStringFromClass([service class]) isEqualToString:serviceImpName]) { 135 | return service; 136 | } 137 | } 138 | NSLog(@"服务未启动!"); 139 | return nil; 140 | } 141 | #pragma mark -Appdelegate 142 | //将app事件分发到各个运行中的模块 143 | 144 | - (void)applicationDidEnterBackground:(UIApplication *)application 145 | { 146 | for (id mod in _runingModules) { 147 | [mod modDidEnterBackground]; 148 | } 149 | } 150 | @end 151 | -------------------------------------------------------------------------------- /fisherman/FisherMan (容器框架)/FisherManContext.h: -------------------------------------------------------------------------------- 1 | // 2 | // FisherManContext.h 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2019/3/27. 6 | // Copyright © 2019 keruyun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FisherManContext : NSObject 12 | 13 | @property (nonatomic, strong) NSString *profileName; 14 | 15 | + (instancetype)context; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /fisherman/FisherMan (容器框架)/FisherManContext.m: -------------------------------------------------------------------------------- 1 | // 2 | // FisherManContext.m 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2019/3/27. 6 | // Copyright © 2019 keruyun. All rights reserved. 7 | // 8 | 9 | #import "FisherManContext.h" 10 | 11 | @implementation FisherManContext 12 | 13 | + (instancetype)context 14 | { 15 | static dispatch_once_t onceToken; 16 | static FisherManContext *fsmCon = nil; 17 | dispatch_once(&onceToken, ^{ 18 | fsmCon = [[FisherManContext alloc] init]; 19 | }); 20 | return fsmCon; 21 | } 22 | @end 23 | -------------------------------------------------------------------------------- /fisherman/FisherMan (容器框架)/Navigation/FSMNavigationController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSMNavigationController.h 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2019/3/27. 6 | // Copyright © 2019 keruyun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FSMNavigationController : UINavigationController 12 | 13 | - (void)pushViewController:(UIViewController *)viewController type:(NSString *)type; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /fisherman/FisherMan (容器框架)/Navigation/FSMNavigationController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSMNavigationController.m 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2019/3/27. 6 | // Copyright © 2019 keruyun. All rights reserved. 7 | // 8 | 9 | #import "FSMNavigationController.h" 10 | #import "FSMNavigationDelegate.h" 11 | 12 | @interface FSMNavigationController () 13 | 14 | @end 15 | 16 | @implementation FSMNavigationController 17 | { 18 | FSMNavigationDelegate *_fsdelegate; 19 | } 20 | - (instancetype)initWithRootViewController:(UIViewController *)rootViewController { 21 | self = [super initWithRootViewController:rootViewController]; 22 | if (self) { 23 | self.navigationBar.hidden = YES; 24 | _fsdelegate = [[FSMNavigationDelegate alloc] init]; 25 | 26 | self.delegate = _fsdelegate; 27 | } 28 | return self; 29 | } 30 | - (void)viewDidLoad { 31 | [super viewDidLoad]; 32 | } 33 | - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated 34 | { 35 | [self pushViewController:viewController type:@"push"]; 36 | } 37 | - (void)pushViewController:(UIViewController *)viewController type:(NSString *)type 38 | { 39 | _fsdelegate.isPush = [type isEqualToString:@"push"]; 40 | [super pushViewController:viewController animated:YES]; 41 | 42 | } 43 | @end 44 | -------------------------------------------------------------------------------- /fisherman/FisherMan (容器框架)/Navigation/FSMNavigationDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSMNavcDelegate.h 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2019/3/27. 6 | // Copyright © 2019 keruyun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FSMNavigationDelegate : NSObject 12 | 13 | @property (nonatomic, assign) BOOL isPush; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /fisherman/FisherMan (容器框架)/Navigation/FSMNavigationDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSMTransition.m 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2019/3/27. 6 | // Copyright © 2019 keruyun. All rights reserved. 7 | // 8 | 9 | #import "FSMNavigationDelegate.h" 10 | #import "FSMNavigationTransition.h" 11 | 12 | @implementation FSMNavigationDelegate 13 | { 14 | FSMNavigationTransition *_transition; 15 | } 16 | - (instancetype)init 17 | { 18 | self = [super init]; 19 | if (self) { 20 | _transition = [[FSMNavigationTransition alloc] init]; 21 | } 22 | return self; 23 | } 24 | - (id)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC { 25 | if (_isPush) { 26 | return nil; 27 | } 28 | return _transition; 29 | } 30 | @end 31 | 32 | -------------------------------------------------------------------------------- /fisherman/FisherMan (容器框架)/Navigation/FSMNavigationTransition.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSMNavigationTransition.h 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2019/3/27. 6 | // Copyright © 2019 keruyun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface FSMNavigationTransition : NSObject 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /fisherman/FisherMan (容器框架)/Navigation/FSMNavigationTransition.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSMNavigationTransition.m 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2019/3/27. 6 | // Copyright © 2019 keruyun. All rights reserved. 7 | // 8 | 9 | #import "FSMNavigationTransition.h" 10 | 11 | @implementation FSMNavigationTransition 12 | 13 | - (NSTimeInterval)transitionDuration:(id)transitionContext 14 | { 15 | return 0.3; 16 | } 17 | - (void)animateTransition:(id)transitionContext 18 | { 19 | UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; 20 | UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey]; 21 | UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey]; 22 | CGRect toViewFinalFrame = [transitionContext finalFrameForViewController:toVC]; 23 | 24 | [toView setFrame:CGRectMake(0, CGRectGetHeight(toViewFinalFrame), CGRectGetWidth(toViewFinalFrame), CGRectGetHeight(toViewFinalFrame))]; 25 | 26 | [[transitionContext containerView] addSubview:toView]; 27 | 28 | [UIView animateWithDuration:[self transitionDuration:transitionContext] 29 | animations:^{ 30 | [toView setFrame:toViewFinalFrame]; 31 | } 32 | completion:^(BOOL finished) { 33 | if (![transitionContext transitionWasCancelled]) { 34 | [fromView removeFromSuperview]; 35 | [transitionContext completeTransition:YES]; 36 | } 37 | else { 38 | [toView removeFromSuperview]; 39 | [transitionContext completeTransition:NO]; 40 | } 41 | }]; 42 | } 43 | @end 44 | -------------------------------------------------------------------------------- /fisherman/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 | 25 | UIMainStoryboardFile 26 | 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 | -------------------------------------------------------------------------------- /fisherman/Main/Modules(功能模块)/Launcher(首页模块)/LauncherModDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // LauncherModDelegate.h 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FSMModProtocol.h" 11 | 12 | @interface LauncherModDelegate : NSObject 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /fisherman/Main/Modules(功能模块)/Launcher(首页模块)/LauncherModDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // LauncherModDelegate.m 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import "LauncherModDelegate.h" 10 | #import "LauncherModRootViewController.h" 11 | 12 | @implementation LauncherModDelegate 13 | { 14 | LauncherModRootViewController *_rootVC; 15 | } 16 | //模块启动完成 17 | - (void)modDidFinishLaunchingWithOptions:(NSDictionary *)options 18 | { 19 | _rootVC = [[LauncherModRootViewController alloc] init]; 20 | } 21 | //模块的根视图控制器 22 | - (UIViewController *)rootViewControllerForMod 23 | { 24 | return _rootVC; 25 | } 26 | //模块进入后台 27 | - (void)modDidEnterBackground 28 | { 29 | 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /fisherman/Main/Modules(功能模块)/Launcher(首页模块)/LauncherModRootViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // LauncherModRootViewController.h 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface LauncherModRootViewController : UIViewController 14 | 15 | @end 16 | 17 | NS_ASSUME_NONNULL_END 18 | -------------------------------------------------------------------------------- /fisherman/Main/Modules(功能模块)/Launcher(首页模块)/LauncherModRootViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // LauncherModRootViewController.m 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import "LauncherModRootViewController.h" 10 | #import "LoginService.h" 11 | #import "FisherMan.h" 12 | 13 | @interface LauncherModRootViewController () 14 | 15 | @end 16 | 17 | @implementation LauncherModRootViewController 18 | 19 | - (void)viewDidLoad 20 | { 21 | [super viewDidLoad]; 22 | UIButton *loginButton = [UIButton buttonWithType:UIButtonTypeSystem]; 23 | loginButton.frame = CGRectMake(100, 100, 100, 100); 24 | [loginButton setTitle:@"登录" forState:UIControlStateNormal]; 25 | [self.view addSubview:loginButton]; 26 | [loginButton addTarget:self action:@selector(didClikedLoginButton) forControlEvents:UIControlEventTouchUpInside]; 27 | 28 | } 29 | - (void)didClikedLoginButton 30 | { 31 | //调用登录服务· 32 | id loginService = [[FisherMan man] findServiceWithName:@"LoginService"]; 33 | [loginService loginWithUserName:@"xiaowang" passwd:@"123"]; 34 | //启动订单模块 35 | [[FisherMan man] launchModuleWithName:@"TradeMod" parameters:nil transition:FMModTransitionTypePush]; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /fisherman/Main/Modules(功能模块)/Trade(订单模块)/TradeModDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // TradeModAppDelegate.h 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FSMModProtocol.h" 11 | 12 | @interface TradeModDelegate : NSObject 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /fisherman/Main/Modules(功能模块)/Trade(订单模块)/TradeModDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // TradeModAppDelegate.m 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import "TradeModDelegate.h" 10 | #import "TradeModRootViewController.h" 11 | 12 | @implementation TradeModDelegate 13 | { 14 | TradeModRootViewController *_rootVC; 15 | } 16 | - (void)modDidFinishLaunchingWithOptions:(NSDictionary *)options 17 | { 18 | NSLog(@"订单模块启动"); 19 | 20 | _rootVC = [[TradeModRootViewController alloc] init]; 21 | } 22 | - (UIViewController *)rootViewControllerForMod 23 | { 24 | return _rootVC; 25 | } 26 | @end 27 | -------------------------------------------------------------------------------- /fisherman/Main/Modules(功能模块)/Trade(订单模块)/TradeModRootViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TradeViewController.h 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface TradeModRootViewController : UIViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /fisherman/Main/Modules(功能模块)/Trade(订单模块)/TradeModRootViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TradeViewController.m 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import "TradeModRootViewController.h" 10 | #import "LoginService.h" 11 | #import "FisherMan.h" 12 | 13 | @interface TradeModRootViewController () 14 | 15 | @end 16 | 17 | @implementation TradeModRootViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | // Do any additional setup after loading the view. 22 | 23 | id loginService = [[FisherMan man] findServiceWithName:@"LoginService"]; 24 | 25 | UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 300, 20)]; 26 | label.text = [NSString stringWithFormat:@"当前登录用户名:%@",[loginService loginUserName]]; 27 | label.textColor = [UIColor blackColor]; 28 | [self.view addSubview:label]; 29 | 30 | UIButton *loginButton = [UIButton buttonWithType:UIButtonTypeSystem]; 31 | loginButton.frame = CGRectMake(100, 100, 100, 100); 32 | [loginButton setTitle:@"关闭" forState:UIControlStateNormal]; 33 | [self.view addSubview:loginButton]; 34 | [loginButton addTarget:self action:@selector(close) forControlEvents:UIControlEventTouchUpInside]; 35 | 36 | } 37 | - (void)close 38 | { 39 | [[FisherMan man] exitCurrentModule]; 40 | } 41 | 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /fisherman/Main/Services(通用服务)/LoginService(登录服务)/LoginService.h: -------------------------------------------------------------------------------- 1 | // 2 | // LoginService.h 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FSMServiceProtocol.h" 11 | 12 | @protocol LoginService 13 | 14 | - (void)loginWithUserName:(NSString *)userName passwd:(NSString *)passwd; 15 | 16 | - (NSString *)loginUserName; 17 | 18 | @end 19 | 20 | -------------------------------------------------------------------------------- /fisherman/Main/Services(通用服务)/LoginService(登录服务)/LoginServiceImp.h: -------------------------------------------------------------------------------- 1 | // 2 | // LoginServiceImp.h 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "LoginService.h" 11 | 12 | @interface LoginServiceImp : NSObject 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /fisherman/Main/Services(通用服务)/LoginService(登录服务)/LoginServiceImp.m: -------------------------------------------------------------------------------- 1 | // 2 | // LoginServiceImp.m 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. All rights reserved. 7 | // 8 | 9 | #import "LoginServiceImp.h" 10 | 11 | @implementation LoginServiceImp 12 | { 13 | NSString *_userName; 14 | } 15 | - (void)serviceStart 16 | { 17 | NSLog(@"LoginService Start"); 18 | } 19 | - (NSString *)loginUserName 20 | { 21 | return _userName; 22 | } 23 | - (void)loginWithUserName:(NSString *)userName passwd:(NSString *)passwd 24 | { 25 | _userName = userName; 26 | } 27 | @end 28 | -------------------------------------------------------------------------------- /fisherman/MyAppProfile.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Services 6 | 7 | 8 | imp 9 | LoginServiceImp 10 | name 11 | LoginService 12 | 13 | 14 | Modules 15 | 16 | 17 | delegate 18 | LauncherModDelegate 19 | name 20 | LauncherMod 21 | 22 | 23 | name 24 | TradeMod 25 | delegate 26 | TradeModDelegate 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /fisherman/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // fisherman 4 | // 5 | // Created by Chonghua Yu on 2018/11/8. 6 | // Copyright © 2018 keruyun. 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 | --------------------------------------------------------------------------------