美文网首页
神器----URL路由--JLRoutes

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

作者: 我是小胡胡分胡 | 来源:发表于2018-03-22 15:58 被阅读77次

    // 注册一个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 <NSCopying>

    /// 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 <NSString *> *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 <NSCopying>

    /// 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<NSString *,id> * _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

          本文链接:https://www.haomeiwen.com/subject/zliaqftx.html