iOS项目开发技巧iOS

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

2015-11-30  本文已影响126人  Stark_Dylan

WebView与JavaScript交互

/*!
 *  @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

上一篇下一篇

猜你喜欢

热点阅读