美文网首页iOS项目开发技巧iOS
DLJSRouter(JS Call OC)思路以及核心代码

DLJSRouter(JS Call OC)思路以及核心代码

作者: Stark_Dylan | 来源:发表于2015-11-30 08:54 被阅读126次

    WebView与JavaScript交互

    • DLJavascriptRouter -> 拉取当前Web界面JS配置
      在WebView代理方法中调用该方法
    /*!
     *  @brief  WebView 加载完成后拉取JS配置
     */
    - (void)webViewDidFinishLoad;
    

    gapDict 用于存放配置信息, path : 方法名

    #define DLJavascriptGetMapMethodName @"getMethodMap();"
    
    
    - (void)webViewDidFinishLoad {
        
        // 从JS拉取配置
        NSString * result = [_webView stringByEvaluatingJavaScriptFromString:DLJavascriptGetMapMethodName];
        [self.gapDict setValuesForKeysWithDictionary:[self toDict:result]];
    }
    
    • 捕获跳转信息
    
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
        
        return [_router handleWebViewForwardAction:request];
    }
    
    /*!
     *  @brief  捕获WebView 跳转信息, 截取Gap
     */
    - (BOOL)handleWebViewForwardAction: (NSURLRequest *)request;
    
    
    /*!
     *  @brief  捕获WebView 跳转信息, 截取Gap
     */
    - (BOOL)handleWebViewForwardAction: (NSURLRequest *)request {
    
        if (!self.scheme) {
            
            return YES;
        }
        
        NSURL * url = request.URL;
        
        NSString * scheme = url.scheme;
        
        if ([self.scheme isEqualToString:scheme]) {
            
            // 能否处理
            
            NSString * path = url.path;
            NSString * query = url.query;
            
            // 可以处理
            if ([self.gapDict.allKeys containsObject:path]) {
                
                // 处理
                
                id result = [self operatedPathAndQuery:path query:query];
                
                if (result) {
                    
                    // 回掉
                    [self callBack:result path:path];
                }
                
                return NO;
            } else {
                
                return YES;
            }
        }
        
        return YES;
    }
    
    
    - (id)operatedPathAndQuery: (NSString *)path query: (NSString *)query {
        
        // key = value & key = value
        NSArray * queryArray = [query componentsSeparatedByString:@"&"];
        
        NSArray * array = [NSMutableDictionary dictionary];
        
        for (NSString * separateString in queryArray) {
            
            NSArray * tempArray = [separateString componentsSeparatedByString:@"="];
            
            if (tempArray.count == 2) {
                
                NSString * value = tempArray[1];
                
                [array addObject:value];
            }
        }
        
        if (array.count != 0) {
            
            // can operated
            
            NSString * methodName = [self.gapDict valueForKey:path];
            SEL selector = NSSelectorFromString:methodName];
            
            // Get method count
            NSInteger methodParamCount = [methodName componentsSeparatedByString:@":"].count;
            
            NSMethodSignature *signature = [self.handler methodSignatureForSelector:selector];
            
            if (signature) {
                
                NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:sig];
                [invocation setTarget:self.handler];
                [invocation setSelector:selector];
                
                // Set param
                
                for (int i = 1; i < methodParamCount + 1; i ++) {
                    
                    id object = array[i];
                    [invocation setArgument:&object atIndex:i + 1];
                }
                
                [invocation invoke];
                
                if (signature.methodReturnLength) {
                    
                    id resultObject;
                    [invocation getReturnValue:&resultObject];
                    return resultObject;
                    
                } else {
                    
                    return nil;
                }
            } else {
                
                return nil;
            }
        }
    }
    
    - (void)callBack: (id)result path: (NSString *)path {
        
        [self.webView stringByEvaluatingJavaScriptFromString:@"dl_callBack('%@', '%@');", path, result];
    }
    
    1. 获取Request中的scheme、path、query, 并判断scheme是否对应, path是否存在与JS配置的存放处gapDict中
    2. 处理query, 并且通过NSInvocation执行方法, 并且允许传入多个参数
    3. 获取方法执行结果, 如果有的话, 回掉JS

    copyRight@DylanWild 2015-11-30

    相关文章

      网友评论

        本文标题:DLJSRouter(JS Call OC)思路以及核心代码

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