神器----URL路由--JLRoutes

// 注册一个url,并绑定目标页面控制器,控制器回调数据的block,以便JXBRouter用此url打开。

// url的scheme+path部分作为key,value为控制器的名字和回调handler的block,保存到单例对象的字典中。 

[JXBRouter registerRoutePattern:@"demo://Amodule/product/list" targetControllerName:@"CViewController" handler:^(NSString *handlerTag, id parameters) {
   
}];
//  url的方式打开一个页面;url的scheme+path作为key查找控制器名字。使用运行时,调用控制器名字的create方法, 把url中的参数传递过去
[JXBRouter startRoute:@"demo://Amodule/product/list?title=C控制器"];

UIViewController 扩展一个回调方法handlerBlock

// 注册一个url;;绑定一个block

[MGJRouter registerURLPattern:@"mgj://detail" toHandler:^(NSDictionary *routerParameters) {
NSLog(@"匹配到了 url, 一会会执行 Completion Block");

// 模拟 push 一个 VC
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    void (^completion)(id result) = routerParameters[MGJRouterParameterCompletion];
    if (completion) {
        completion(nil);
    }
});

}];

// 通过URL打开某个handler,参数通过url的query匹配一部分,第二部分通过withUserInfo传递, 参数在handler的block参数中获取
[MGJRouter openURL:@"mgj://detail" withUserInfo:nil completion:^(id result){
[self appendLog:@"Open 结束,我是 Completion Block"];
}];

CTMediator
NSInvocation

  • (id)performActionWithUrl:(NSURL *)url completion:(void(^)(NSDictionary *info))completion;
    // 本地组件调用入口
  • (id)performTarget:(NSString *)targetName action:(NSString *)actionName params:(NSDictionary *)params shouldCacheTarget:(BOOL)shouldCacheTarget;

JLRoutes

/////1 嵌套,Route嵌套Route;第一层由字典保存,scheme自己指定,内容为JLRoutes; 第二层由urlPattern的scheme指定,内容为JLRRouteDefinition结构

static NSMutableDictionary *JLRGlobal_routeControllersMap = nil;

JLRoutes *routesController = nil;

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    JLRGlobal_routeControllersMap = [[NSMutableDictionary alloc] init];
});

if (!JLRGlobal_routeControllersMap[scheme]) {
    routesController = [[self alloc] init];
    routesController.scheme = scheme;
    JLRGlobal_routeControllersMap[scheme] = routesController;
}

routesController = JLRGlobal_routeControllersMap[scheme];

return routesController;

@interface JLRoutes ()

@property (nonatomic, strong) NSMutableArray *mutableRoutes;

/// 2 绑定 入口数据保存结构

@interface JLRRouteDefinition : NSObject

/// The URL scheme for which this route applies, or JLRoutesGlobalRoutesScheme if global.
@property (nonatomic, copy, readonly) NSString *scheme;

/// The route pattern.
@property (nonatomic, copy, readonly) NSString *pattern;

/// The priority of this route pattern.
@property (nonatomic, assign, readonly) NSUInteger priority;

/// The route pattern path components.
@property (nonatomic, copy, readonly) NSArray *patternPathComponents;
///// self.patternPathComponents = [pattern componentsSeparatedByString:@"/"];

/// The handler block to invoke when a match is found.
@property (nonatomic, copy, readonly) BOOL (^handlerBlock)(NSDictionary *parameters);

//// 3 调用 入口数据再一次转化;;; 主要是处理url中的fragment(是否需要将fragment中的query增加到queryParams参数)和query参数。以及path的处理(是否将host当作path的一部分)

@interface JLRRouteRequest : NSObject

/// The URL being routed.
@property (nonatomic, copy, readonly) NSURL *URL;

/// The URL's path components.
@property (nonatomic, strong, readonly) NSArray *pathComponents;

/// The URL's query parameters.
@property (nonatomic, strong, readonly) NSDictionary *queryParams;

/// Route request options, generally configured from the framework global options.
@property (nonatomic, assign, readonly) JLRRouteRequestOptions options;

/// Additional parameters to pass through as part of the match parameters dictionary.
@property (nonatomic, copy, nullable, readonly) NSDictionary *additionalParameters;

////// 4 根据入口,在路由中搜寻 handler回调。 这样就使得url-----handler一一对应起来

pragma mark - Main API

JLRRouteRequestOptions options = [self _routeRequestOptions];
JLRRouteRequest *request = [[JLRRouteRequest alloc] initWithURL:URL options:options additionalParameters:parameters];

for (JLRRouteDefinition *route in [self.mutableRoutes copy]) {
    // check each route for a matching response
    JLRRouteResponse *response = [route routeResponseForRequest:request]; //// 该方法主要是解析pattern,解析是否匹配,并生成对应的参数
    if (!response.isMatch) {
        continue;
    }
    
    [self _verboseLog:@"Successfully matched %@", route];
    
    if (!executeRouteBlock) {
        // if we shouldn't execute but it was a match, we're done now
        return YES;
    }
    
    [self _verboseLog:@"Match parameters are %@", response.parameters];
    
    // Call the handler block
    didRoute = [route callHandlerBlockWithParameters:response.parameters];
    


    if (didRoute) {
        // if it was routed successfully, we're done - otherwise, continue trying to route
    //执行一个block表示搜寻完成
        break;
    }

@interface JLRRouteResponse : NSObject

/// Indicates if the response is a match or not.
@property (nonatomic, assign, readonly, getter=isMatch) BOOL match;

/// The match parameters (or nil for an invalid response).
@property (nonatomic, copy, readonly, nullable) NSDictionary *parameters;

/// Check for route response equality

  • (BOOL)isEqualToRouteResponse:(JLRRouteResponse *)response;

///////////5

[[JLRoutes globalRoutes] addRoute:@"/:user/:phone/view/:userId/:password" handler:^BOOL(NSDictionary * _Nonnull parameters) {

{
"JLRouteURL": "(the NSURL that caused this block to be fired)",
"JLRoutePattern": "(the actual route pattern string)",
"JLRouteScheme": "(the route scheme, defaults to JLRoutesGlobalRoutesScheme)"
}
JLRoutePattern = "/:user/:phone/view/:userId/:password";
JLRouteScheme = JLRoutesGlobalRoutesScheme;
JLRouteURL = "urlschemedemo3://user/18611111111/view/joeldev/12345?a=5&b=6";
a = 5;
b = 6;
c = 7;
password = 12345;
phone = 18611111111;
user = user;
userId = joeldev;

    return YES;
}];
 
NSURL *viewUserURL = [NSURL URLWithString:@"urlschemedemo3://user/18611111111/view/joeldev/12345?a=5&b=6"];
[JLRoutes routeURL:viewUserURL withParameters:@{@"c":@"7"}];

你可能感兴趣的:(神器----URL路由--JLRoutes)