什么是业务组件和弱业务组件?
业务组件里面基本都有:storyboard、nib、图片等等。弱业务组件里面一般没有。这不是绝对的,但一般情况是这样。 业务组件一般都是App上某一具体业务。比如首页、我、直播、行情详情、XX交易大盘、YY交易大盘、XX交易中盘、资讯、发现等等。而弱业务组件是给这些业务组件提供功能的,一般自己不直接表现在App上展示。
代码截取:
@implementation PBBasicProviderModule YTXMODULE_EXTERN() { } + (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions { [self setupThirdParty:application didFinishLaunchingWithOptions:launchOptions]; [self setupBasic:application didFinishLaunchingWithOptions:launchOptions]; return YES; } + (void) setupThirdParty:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ [self setupEaseMob:application didFinishLaunchingWithOptions:launchOptions]; [self setupTalkingData]; [self setupAdTalkingData]; [self setupShareSDK]; [self setupJSPatch]; [self setupUmeng]; // [self setupAdhoc]; }); } + (void) setupBasic:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [self registerBasic]; [self autoIncrementOpenAppCount]; [self setupScreenShowManager]; [self setupYTXAnalytics]; [self setupRemoteHook]; } + (YTXAnalytics) sharedYTXAnalytics { return ......; } ......
《iOS App组件化开发实践》介绍的层级结构设计图:
《iOS App组件化开发实践》推行的组件化规范:
- 业务组件之间不能有依赖关系。
- 按照图示不能跨层依赖。
- 所谓弱业务组件就是包含着少部分业务,并且可以在这个App内的各个业务组件之间重用的代码。
- 要依赖YTXModule的组件一定要以Module结尾,而且它一定是个业务组件或是弱业务组件。
- 弱业务组件以App代号开头(比如PB),以Module结尾。例:PBBasicProviderModule。
- 业务组件以App代号开头(比如PB)BusinessModule结尾。例:PBHomePageBusinessModule。
- 业务组件之间不能有依赖关系,这是公认的的原则。否则就失去了组件化开发的核心价值。
由于引入PBBasicProviderModule解决AppDelegate中的各种问题,会导致PBBasicProviderModule体量激增,以下是《iOS App组件化开发实践》中的解决方案。
据说美团的组件化开发必须依赖主App的AppDelegate的一大堆设置和初始化。所以干脆他们就直接在主App中集成调试,他们通过二进制化和去Pod依赖化的方式让主App的构建非常快。
所以我们是不是可以继续污染这个PBBasicProviderModule。不需要在主App项目里的AppDelegate写任何初始化代码?基本或者尽量不在主App里写任何代码?改依赖主App变为依赖这个弱业务组件?
按照这个思路我们搬空了AppDelegate里的所有代码。比如一些初始化App样式的东西、初始化RootViewController等等这些都可以搬到一个新的弱业务组件里。
而业务组件其实根本不需关心这个弱业务组件,开发人员只需要在业务组件中的Example App中的AppDelegate中初始化自己业务组件的RootViewController就好了。
其他的事情交给这个新的弱业务组件就好了。而主App和Example App只要在Podfile中依赖它就好了。
所以最后的设想就是:开发者不会去改主App项目,也不需要知道主App项目。对于开发者来说,主App和业务组件之间是隔绝的。
上面这些表示一脸懵逼,来源下面有地址,大家自行理解。
坑点之 Debug/Release:
在对二进制Pod库跑测试的发现,源码能过,二进制(.a)不能过。 问题源头(这是二进制化的锅):
#ifdef DEBUG #endif
由于DEBUG在编译阶段就已经决定了。二进制化的时候已经编译完成了。
解决方案:
创建了一个 PBEnvironmentProvider 大家都去依赖它。
然后原来判断宏的代码改成这样:
if([PBEnvironmentProvider testing]) { //... }
在主App的AppDelegate中这样:
#if DEBUG && TESTING //PBEnvironmentProvider提供的宏 CONFIG_ENVIRONMENT_TESTING #endif
原理是: 如果AppDelegate有某个方法(CONFIG_ENVIRONMENT_TESTING宏会提供这个方法),[PBEnvironmentProvider testing]得到的结果就是YES。
业务组件间通信
App路由能解决哪些问题:
1)3D-Touch功能或者点击推送消息,要求外部跳转到App内部一个很深层次的一个界面。
2)自家的一系列App之间如何相互跳转?
3)如何解除App组件之间和App页面之间的耦合性?
4)如何能统一iOS和Android两端的页面跳转逻辑?甚至如何能统一三端的请求资源的方式?
5)如果使用了动态下发配置文件来配置App的跳转逻辑,那么如果做到iOS和Android两边只要共用一套配置文件?
6)如果App出现bug了,如何不用JSPatch,就能做到简单的热修复功能?
7)如何在每个组件间调用和页面跳转时都进行埋点统计?每个跳转的地方都手写代码埋点?利用Runtime AOP ?
8)如何在每个组件间调用的过程中,加入调用的逻辑检查,令牌机制,配合灰度进行风控逻辑?
9)如何在App任何界面都可以调用同一个界面或者同一个组件?只能在AppDelegate里面注册单例来实现?
App之间跳转实现
1)URL Scheme方式 2)Universal Links方式
组件间通信的三方库支持也有许多如:
- 1.主流的有类似JLRoutes,主打通过URL跳转协议(https://github.com/joeldev/JLRoutes)
- 2.HHRouter:这是布丁动画的一个Router,灵感来自于 ABRouter 和 Routable iOS。
- 3.美丽联合开源的三方库MGJRouter(https://github.com/meili/MGJRouter),使用项目包括旗下的:蘑菇街、美丽说等。
关于JLRoutes简单介绍:《iOS 模块化之 JLRoute 路由示例 (中英文)》(https://github.com/ReverseScale/JLRouteDemo)