TestsTested | ✗ |
LangLanguage | Obj-CObjective C |
License | MIT |
ReleasedLast Release | May 2017 |
Maintained by qiaomu, halfrost, EyreFree.
LPDModularKit is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod "LPDModularKit"
foxsofter, [email protected]
###背景 app的业务越来越复杂,跨app的业务模块开始出现,如何模块化?同一个app中使用的技术可能包括MVC、MVVM、H5、React Native,如何更好的融合各项技术?开发人员开始膨胀,如何解耦开发人员?要解决上述问题,必须具备模块化的能力。so,lpd-modular-kit的出现就是为了解决上述问题。 ###一切都是为了解耦 本案最基本的要解决的问题就是模块间解耦,解耦不是完全不相干了,而是将耦合最小化。模块间本身已经存在一类不可避免的耦合,那就是页面跳转。而模块间还存在一类耦合,那就是模块间的相互调用,这一类耦合是我们要去重点解耦的。 页面跳转的解耦方式目前主流做法是通过url router来实现的,这也是iOS系统提供的一种方式,最好直接用起来。另外的模块间调用,这一类不是强需求,但是会存在,还是得提供一个方案,本案的做法是将这一类耦合也通过url router来实现,最小化解耦代价。 ###URL设计 ####URL Scheme URL的Scheme区分inter-app,in-app,如inter-app:me.ele.lpd,in-app:lpd,app内部两者都可以访问,外部app访问的Scheme只能是me.ele.lpd,模块内部可以自行决定是否允许外部app访问。 ####URL for action [scheme]://[modular]/[target]/[action]?[parameters] modular是模块的唯一标识,target是模块下面的某一类型的唯一标识,target是模块对外暴露的接口类,action是接口类所提供的函数的签名,parameters所对应的就是函数的参数。 ####URL for push|present [scheme]://[modular]/[target]/[push|present]?[parameters] 在MVC框架下,target表示UIViewController的唯一标识,在MVVM框架下,target表示LPDViewModelProtocol的子类的唯一标识,parameters所对应的就是target提供的属性。
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