项目改造的需要,重新捣弄了路由的代码,抽离出来「路由组件」。
设计目标
目前大部分的开源路由组件其实已经可以满足基本需求了,比如参数解析、scheme分离等JLRoutes也都支持。但有些别的特性,比如拦截器,比如更动态的配置,还需要重新实现,这也是本文的「路由组件」的主要目标。路由只是路由,关于模块化与路由,以前有简单表达过自己的看法,这里不再赘述。
本文将用接口的方式简要介绍「路由组件」的功能。
拦截器
场景挺常见的。
拦截器接口定义如下:
1 2 3 4 5 6 7 8 9 10
| typedef void(^HTRouteInterceptorResultBlock)(BOOL pass, id<HTRouteRequestProtocol>_Nullable redirectRequest);
//! 路由拦截器 @protocol HTRouteInterceptorProtocol <NSObject>
- (NSInteger)interceptorLevel; //! 拦截器的意义要求此方法须同步方式执行 - (void)onRoute:(id<HTRouteDefinitionProtocol>)route request:(id<HTRouteRequestProtocol>)request result:(HTRouteInterceptorResultBlock)result;
@end
|
对于一个可路由的URL
,在发起路由请求后、实际执行路由前,我们提供拦截的机会:
- 中断路由
- 延迟路由
- 转发路由
拦截器由业务方定义的,只要遵循接口并在运行时注入到路由系统即可。
中断路由,是对于一些极端情况处理;延迟路由比较常见,比如对于用户未登录的情况,需要跳转到登录页面执行完登录流程后,再执行路由;转发路由也比较容易理解。
路由定义
想要支持
- 多路径匹配,也就需要允许匹配一个路由后,可以允许继续进行后续的匹配;
- 匹配模式,是否严格匹配、或是允许fallback;
- 数据响应,允许返回Object;
以下是路由的定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| //! 路由定义 @protocol HTRouteDefinitionProtocol <NSObject>
@property (nonatomic, assign) HTRouteMatchMode matchMode;// 匹配模式 @property (nonatomic, assign) BOOL continueNext;// 匹配成功后是否允许后续匹配 @property (nonatomic, assign) CGFloat priority;// 优先级 @property (nonatomic, assign) BOOL skipInterception;// 拦截器
@property (nonatomic, copy, readonly) NSString *scheme; @property (nonatomic, copy, readonly) NSString *pattern; @property (nonatomic, copy, readonly) NSArray <NSString *> *patternPathComponents; @property (nonatomic, copy, readonly) HTRouteHandlerBlock handlerBlock; @property (nonatomic, copy, readonly) HTRouteObjectBlock objectBlock;// 待定
- (instancetype)initWithRoutePattern:(NSString *)pattern handlerBlock:(HTRouteHandlerBlock)handlerBlock; - (instancetype)initWithRoutePattern:(NSString *)pattern objectBlock:(HTRouteObjectBlock)objectBlock;
- (id<HTRouteResponseProtocol>)routeResponseForRequest:(id<HTRouteRequestProtocol>)request; - (BOOL)executeWithResponse:(id<HTRouteResponseProtocol>)response callback:(HTRouteCompletionBlock)callback;
@end
|
动态配置
指的是,可以在添加路由时,单独针对单个路由动态配置。
接口定义如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @protocol HTRouterConfigurationProtocol <NSObject, NSCopying>
@property (nonatomic, copy, readonly) id<HTRouterConfigurationProtocol> _Nonnull (^match)(HTRouteMatchMode matchMode); @property (nonatomic, copy, readonly) id<HTRouterConfigurationProtocol> _Nonnull (^prefer)(HTRoutePreferOption preferOption); @property (nonatomic, copy, readonly) id<HTRouterConfigurationProtocol> _Nonnull (^transition)(HTRouteTransitionType transition); @property (nonatomic, copy, readonly) id <HTRouterConfigurationProtocol> _Nonnull (^addParameters)(NSDictionary *parameters); @property (nonatomic, copy, readonly) id <HTRouterConfigurationProtocol> _Nonnull (^addInterceptor)(id<HTRouteInterceptorProtocol> interceptor);
@property (nonatomic, assign, readonly) HTRoutePreferOption preferOption; @property (nonatomic, assign, readonly) HTRouteTransitionType transitionType; @property (nonatomic, assign, readonly) HTRouteMatchMode matchMode; @property (nonatomic, strong, readonly, nullable) NSDictionary<NSString *,id> *parameters; @property (nonatomic, strong, readonly, nullable) NSArray *interceptors;
@end
|
还差什么?
首先,实现上可能还有bug,不过明显的bug肯定是容易发现、修复的。设计上的问题,可能要做一定调整。
再者,没有类似Java的注解功能,一些语法糖还不支持(但折腾宏的话,其实可以实现一部分的)。
另一方面,我们也要思考,需不需要,适不适合,值不值得。路由库尽量只做路由库的功能,业务嵌入的部分是要单独适配的。不是很喜欢侵入性太高的方案。
Comments