首先,今天写的JS交互要感谢-- 宇神(向晨宇)给写的的demo 共我们学习
JS交互在我的理解中把他分为了--简洁版 与 --动态版
简洁版:就是今天要写的根据获取Web的代理获取"NSURLRequest"后,转化为字符串,进行比较后调用相应地方法。
动态版:JSPatch中实现了通过 Runtime 接口调用和替换 OC 方法,从而得到实时的方法。至于为什么不写这个动态版的,主要是因为JSPatch的链接中已经写了很多了:JSPatch实现原理详解,还有一个小原因是。。司小文的脑袋真的不够使...看个大概还行,往深里看再写出来就不成了。(好吧确实这个才是主要的)。
那接下来咱们依然代码加注释,赶紧写完赶紧去浪。
首先,这个交互需要后台和你配合,定义出一个你们共同的暗号。(比如 xxx 或者 SiXiaoWenBangBangDa 这样的)
这个给后台看:
<html> <!--描述网页信息--> <head> <meta charset="UTF-8"/> <title>iOS上webView与JS交互的demo</title> <script> function show() { alert('你调用了show->1'); } function showTitle() { alert(document.title); } function showTitleMessage(message) { alert(message); } function repost() { location.href = "http://www.iosxxx.com"; } function sum() { return 1 + 1; } function btnClick() { <!--xmg://sendMessageWithNumber_andContent_?10086&love--> location.href = "xmg://callWithNumber_?15830654880"; } </script> </head> <!--网页具体内容--> <body> <br>电话号码: 11111111</br> <br>邮箱: [email protected]</br><br/> <button style = "background: red; height: 150px; width: 150px;" onclick = "btnClick();">按钮</button> </body> </html>
#pragma mark-JSCallOC - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { //打印看下URL NSLog(@"%@", request.URL); //这个@"xmg://"就是和后台定的暗号 NSString *schem = @"xmg://"; //把NSURLRequest转换成字符串的形式 NSString *urlStr = [request.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; //判断暗号是否一样,一样的话进入我们需要调用OC方法 if ([urlStr hasPrefix:schem]) { // 1.从URL中获取方法名称 (去除"xmg://callWithNumber_?15830654880"中的@"xmg://") // 此时 subPath = callWithNumber_?15830654880; NSString *subPath = [urlStr substringFromIndex:schem.length]; // 注意: 如果指定的用于切割的字符串不存在, 那么就会返回整个字符串 // 切割字符串获得数组中元素:callWithNumber_ 与 15830654880; NSArray *subPaths = [subPath componentsSeparatedByString:@"?"]; // 2.获取方法名称--数组中首元素callWithNumber_为方法名 // 把方法名中的_换成冒号 NSString *methodName = [subPaths firstObject]; methodName = [methodName stringByReplacingOccurrencesOfString:@"_" withString:@":"]; // 3.调用方法 // 讲方法名生成一个方法sel SEL sel = NSSelectorFromString(methodName); // 4.处理参数 NSString *parma = nil; if (subPaths.count == 2) { //获取数组中的最后一个元素为电话15830654880 parma = [subPaths lastObject]; // 3.截取参数 (保险起见如果有&去除调) NSArray *parmas = [parma componentsSeparatedByString:@"&"]; #pragma clang diagnostic ignored "-Warc-performSelector-leaks" //去通过刚才生成的方法sel(callWithNumber:) 传入参数电话15830654880 由self调用 //- (void)callWithNumber:(NSString *)numbe [self performSelector:sel withObject:[parmas firstObject] withObject:[parmas lastObject]]; #pragma clang diagnostic pop return NO; } //这里处理参数很麻烦,我们可以自己实现一个类去将苹果自带的方法进行优化,其实就是可以传递不同的参数(多个)去处理相应的事件 [self performSelector:sel withObject:parma]; return NO; } return YES; } // callWithNumber: - (void)callWithNumber:(NSString *)number{ NSLog(@"打电话给%@", number); [self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"showTitleMessage('%@')", number]]; }
当然了除了JSCallOC的方法,我们也有OC呼叫JS的方法这个也需要后台来帮你完成,function showTitle() --- 看上面给后台的这个方法
我们现在用OC的方法来呼叫,非常简单 因为系统已经集成在了 web方法里
#pragma mark-ocCallJS -(void) ocCallJS { [self.webView stringByEvaluatingJavaScriptFromString:@"showTitle();"]; }
感谢观看,学以致用更感谢。