DLJSRouter(JS Call OC)思路以及核心代码
2015-11-30 本文已影响126人
Stark_Dylan
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];
}
- 获取Request中的scheme、path、query, 并判断scheme是否对应, path是否存在与JS配置的存放处gapDict中
- 处理query, 并且通过NSInvocation执行方法, 并且允许传入多个参数
- 获取方法执行结果, 如果有的话, 回掉JS
copyRight@DylanWild 2015-11-30