UIWebView是IOS SDK中渲染网面的控件,在显示网页的时候,咱们能够hack网页而后显示想显示的内容。其中就要用到javascript的知识,而UIWebView与javascript交互的方法就是stringByEvaluatingJavaScriptFromString:javascript
有了这个方法咱们能够经过objc调用javascript,能够注入javascript。html
首先咱们来看一下,如何调用javascript:java
这儿myFunction()就是咱们的javascript方法。git
再来看看入何注入javascript,咱们先写一个须要注入的javascript:github
保存为test.js,而后拖到xcode 的resource分组下。再用代码在初始化的时候注入这个js(如在viewDidLoad方法里)。web
这样就注入了上面的js,那么咱们能够随时调用js的方法,如何调用,上面有介绍。xcode
那么咱们能不能经过js来调用objc的方法呢。 固然能够,原理就是利用UIWebView重定向请求,传一些命令到咱们的UIWebView,在UIWebView的delegate的方法中接收这些命令,并根据命令执行相应的objc方法。这样就至关于在javascript中调用objc的方法。提及来有点抽象,看看代码一下就明白。浏览器
首先咱们写一个javascript 方法以下:app
而后在你的html里调用这个js方法 如: 框架
最后咱们在UIWebVew中截获这个重定向请求:
不过有一个开源工程你们能够看看,它容许javascript调用objective_c的方法。叫
jsbridge-to-cocoa http://code.google.com/p/jsbridge-to-cocoa/
还有两个相关工程
WebViewJavascriptBridge 与 GAJavaScript 值得你们慢慢研究。
其余
插入js代码
上面的功能咱们能够封装到一个js函数中,将这个函数插入到页面上执行,代码以下:
if ([title compare: @"Google"]==NSOrderedSame ) {
[webView stringByEvaluatingJavaScriptFromString:@"var script = document_createElement_x_x('script');"
"script.type = 'text/javascript';"
"script.text = "function myFunction() { "
"var field = document.getElementsByName('q')[0];"
"field.value='朱祁林';"
"document.forms[0].submit();"
"}";"
"document.getElementsByTagName_r('head')[0].a(script);"];
[webView stringByEvaluatingJavaScriptFromString:@"myFunction();"];
}
看上面的代码:
a、首先经过js建立一个script的标签,type为'text/javascript'。
b、而后在这个标签中插入一段字符串,这段字符串就是一个函数:myFunction,这个函数实现google自动搜索关键字的功能。
c、而后使用stringByEvaluatingJavaScriptFromString执行myFunction函数。
1. 通常调用
将本地数据,封装,直接做为JS的返回值。如:获取软件的APPCode
//获取APPCode
NSArray *_plist_paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *_plist_paths_path=[_plist_paths objectAtIndex:0];
NSArray *_plist_array= [_plist_paths_path componentsSeparatedByString:@"/"];
NSString *_appcode=[[NSString alloc]init];
for (NSString *item in _plist_array) {
if ([item length]==36) {
_appcode=item;
break;
}
}
NSLog(@"current appcode:%@",_appcode);//注入到js中
NSMutableString *_getApkCode=[[NSMutableString alloc]init];
[_getApkCode appendFormat:@" function _getApkCode(){"];
[_getApkCode appendFormat:@"return '%@';",_appcode];
[_getApkCode appendString:@" }"];
[self.webView stringByEvaluatingJavaScriptFromString:_getApkCode];
[_getApkCode release];
2.须要跟平台进行交互调用
思路:
1.制造含有必定含义的请求如:(location.href="download");
2.在方法:-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType中,拦截:
//testMall:http://192.168.1.20:8083本地测试页面地址
NSString *pre_download=[NSString stringWithFormat:@"%@downLoad",testMall];
if([url hasPrefix:pre_download])
{//下载代码。。。。
}
3. 注意事项
a.存在Iframe嵌套的页面,js注入
页面注入JS是注入到,浏览器的html中,对于内部嵌套iframe框架的页面,则没法调用到js。此时至关于调用父页面的JS。
能够经过parent+方法名,来调用你注入的JS。parent.parent的使用个数,能够是多个,不影响js的执行,若是少用parent,可能会致使,调不到你注入的JS
b.存在交互的处理方法。推荐使用方法,iphone只负责提供js接口,不调用html内部或其余的js接口
示例:
html
function addDownload()
{
url='www.XXX.XXX.zip';
download(url);//调用iphone提供的js接口
addDownloadTask_ret();//获取iphone下载接口执行的下载结果,此处调的是本地的一个延迟方法
}
//获取iphone下载接口执行的下载结果
function addDownloadTask_ret()
{var obj=getDownloadTaskResult();//此处为iphone提供的接口,负责返回当前下载执行状况的结果if(''!=obj||undefined!=obj)
{
//调用本地的一些后续处理方法。
}
else
{
setTimeout("addDownloadTask_ret2();",1000);
}