LPDModularKit 通过 CocoaPods 提供。要安装它,只需在 Podfile 中添加以下行:
pod "LPDModularKit"
foxsofter, [email protected]
###背景 app的业务越来越复杂,跨app的业务模块开始出现,如何模块化?同一个app中使用的技术可能包括MVC、MVVM、H5、React Native,如何更好的融合各项技术?开发人员开始膨胀,如何解耦开发人员?要解决上述问题,必须具备模块化的能力。因此,lpd-modular-kit的出现就是为了解决这些问题。###一切都是为了解耦 本案最基本要解决的问题就是模块间解耦,解耦不是完全不相干了,而是将耦合最小化。模块间本身已经存在一类不可避免的耦合,那就是页面跳转。而模块间还存在一类耦合,那就是模块间的相互调用,这一类耦合是我们要重点解耦的。页面跳转的解耦方式目前主流的做法是通过url router来实现,这也是iOS系统提供的一种方式,最好直接用起来。另外的模块间调用,这一类不是强需求,但是会存在,还是得提供一个方案。本案的做法是将这一类耦合也通过url router来实现,最小化解耦代价。
push和present可以当成导航的action来看待,所以url的结构是统一的。
###类图
###LPDModularRouter
- (BOOL)openURL:(NSURL *)url options:(nullable NSDictionary<NSString *, id> *)options;
这个接口主要用来处理外部app的url调用,类似于
#ifdef __IPHONE_9_0
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
return [[LPDModularRouter sharedInstance] openURL:url options:options];
}
#else
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation {
return [[LPDModularRouter sharedInstance] openURL:url options:@{ @"sourceApplication" : sourceApplication, @"annotation" : annotation }];
}
#endif
- (BOOL)performActionWithUrl:(NSURL *)url;
- (BOOL)performActionWithUrl:(NSURL *)url completion:(nullable void(^)(__nullable id x))completion;
这两个接口主要处理的时in-app调用,如果是action,action的参数最多支持7个,当然url中的参数必须覆盖到action的参数,可以多传,对于push和present,对传递参数的个数并没有限制,url中的参数和LPDViewTargetProtocol子类所定义的属性遵循对应上则匹配的原则。参数类型目前只支持NSString,并不是完善的RPC调用,然而应该够了。
###LPDModular、LPDTarget objective-c中并没有很好的办法用来隔离模块,本案中也没能明确划分模块,在代码层面可以理解成通过solution来隔离模块。 每个模块都是虚拟的,模块需要实现一个类,此类实现了LPDModularProtocol,每个模块可以自定义LPDModularProtocol中的方法,达到根据需要处理Router的url。
- (BOOL)performActionWithTarget:(Class)targetClass
action:(NSString*)actionName
parameters:(NSDictionary *)parameters
completion:(void(^)(id x))completion;
- (BOOL)pushWithTarget:(Class)targetClass
parameters:(NSDictionary *)parameters
completion:(void(^)(id x))completion;
- (BOOL)presentWithTarget:(Class)targetClass
parameters:(NSDictionary *)parameters
completion:(void(^)(id x))completion;
@interface LPDViewTargetProtocol : LPDTargetProtocol
@property (nonatomic, copy, readonly) NSString *modular;
@property (nonatomic, copy) void (^completion)(id);
@end