.js和xcode交互
来源:互联网 发布:淘宝不卖优酷会员了 编辑:程序博客网 时间:2024/06/08 15:00
本文为您图文演示如何在 OC 中注册或运行 JS 函数,以实现网页与程序的交互。
首先我们创建一个 XCode 项目
将 Webview 拖入 View Controller 中
打开 ViewController.h 新建一个 WebController Interface 继承 NSObject
#import <WebKit/WebKit.h> @interface WebController : NSObject{ IBOutlet WebView* webView;}@end
在项目中添加 Webkit.framework 的引用
将一个 Object 拖拽至 ViewController 并填写其 Class 属性为 WebController
右键点击 WebController 并将 webView 关联起来
接下来就是关键代码 实现 WebController
@implementation WebController+(NSString*)webScriptNameForSelector:(SEL)sel{ if(sel == @selector(Writelog:)) //JS对应的本地函数 return @"log"; // 要注册的JS函数名 else if(sel == @selector(alert:)) return @"alert"; return nil;}+ (BOOL)isSelectorExcludedFromWebScript:(SEL)sel{ if(sel == @selector(Writelog:))//JS对应的本地函数 return NO; else if(sel == @selector(alert:)) return NO; return YES; //返回 YES 表示函数被排除,不会在网页上注册}- (void)awakeFromNib //当 WebContoller 加载完成后执行的动作{ [webView setFrameLoadDelegate:self]; [[webView mainFrame] loadHTMLString:@"<button onclick=\"window.external.alert('This is an alert!!');\">Alert</button> <button onclick=\"window.external.log('lllllaaaa');\">Log</button>" baseURL:nil]; //网页内容,两个按钮 一个弹出消息框,一个在控制台 Log // webView.mainFrameURL = @"http://someurl"; 加载网页}- (void)Writelog:(NSString*) txt{ NSLog(@"Log:%@",txt);}- (void)alert:(NSString*) txt{ NSAlert *alert = [[NSAlert alloc] init]; [alert setAlertStyle:NSInformationalAlertStyle]; [alert setMessageText:@"来自网页的消息"]; [alert setInformativeText:txt]; [alert runModal];}- (void)webView:(WebView *)sender didClearWindowObject:(WebScriptObject *)windowScriptObject forFrame:(WebFrame *)frame //网页加载完成后发生的动作{ [windowScriptObject setValue:self forKeyPath:@"window.external"]; // 注册一个 window.external 的 Javascript 类}@end
然后点击运行按钮 出现应用主界面并自动加载网页内容,此时我们点击 Log 就会在控制台输出数据,点击 Alert 按钮就会弹出提示框。
UIWebView是IOSSDK中渲染网面的控件,在显示网页的时候,我们可以hack网页然后显示想显示的内容。其中就要用到javascript的知识,而UIWebView与javascript交互的方法就是stringByEvaluatingJavaSc
有了这个方法我们可以通过objc调用javascript,可以注入javascript。
首先我们来看一下,如何调用javascript:
- [webView
stringByEvaluatingJavaSc "myFunction();"];riptFromString:@
再来看看入何注入javascript,我们先写一个需要注入的javascript:
- function
showAlert() { -
alert( show );alert' - }
- NSString
*filePath "test"= [[NSBundle mainBundle] pathForResource:@ ofType:@ "js"]; - NSString
*jsString = [[NSString alloc] initWithContentsOfFile:filePath]; - [webView
stringByEvaluatingJavaSc riptFromString:jsString];
那么我们能不能通过js来调用objc的方法呢。当然可以,原理就是利用UIWebView重定向请求,传一些命令到我们的UIWebView,在UIWebView的delegate的方法中接收这些命令,并根据命令执行相应的objc方法。这样就相当于在javascript中调用objc的方法。说起来有点抽象,看看代码一下就明白。
首先我们写一个javascript 方法如下:
- function
sendCommand(cmd,param){ -
var url= "testapp:"+cmd+":"+param; -
document.location = url; - }
- function
clickLink(){ -
sendCommand("alert","你好吗?"); - }
然后在你的html里调用这个js方法如:
- "button"
value= "Clickme!" onclick= "clickLink()"/>
最后我们在UIWebVew中截获这个重定向请求:
- #pragma
mark -- - #pragma
mark UIWebViewDelegate -
- -
( BOOL)webView:(UIWebView*)webView shouldStartLoadWithReque st:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { -
-
NSString *requestString = [[request URL] absoluteString]; -
NSArray *components = [requestString componentsSeparatedByStr ing:@ -
([components "testapp"])count] > 1 && [(NSString *)[components objectAtIndex:0] isEqualToString:@ { -
*)[components "alert"])objectAtIndex:1] isEqualToString:@ -
{ -
UIAlertView *alert = [[UIAlertView alloc] -
initWithTitle:@ from Cocoa Touch" message:[components objectAtIndex:2] -
delegate:self cancelButtonTitle:nil -
otherButtonTitles:@ nil]; -
[alert show]; -
} -
NO; -
} -
YES; - }
jsbridge-to-cocoa
还有两个相关工程
WebViewJavascriptBridge
其他
插入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);"];
[webViewstringByEvaluatingJavaScriptFromString:@"myFunction();"];
}
看上面的代码:
a、首先通过js创建一个script的标签,type为'text/javascript'。
b、然后在这个标签中插入一段字符串,这段字符串就是一个函数:myFunction,这个函数实现google自动搜索关键字的功能。
c、然后使用stringByEvaluatingJavaSc
1.
将本地数据,封装,直接作为JS的返回值。如:获取软件的APPCode
//获取APPCode
NSArray*_plist_paths=NSSearchPathForDirectori esInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString*_plist_paths_path=[_plist_paths objectAtIndex:0];
NSArray *_plist_array= [_plist_paths_pathcomponentsSeparatedByStr ing:@"/"];
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=[[NSMutableStringalloc]init];
[_getApkCode appendFormat:@"function _getApkCode(){"];
[_getApkCodeappendFormat:@"return '%@';",_appcode];
[_getApkCode appendString:@" }"];
[self.webViewstringByEvaluatingJavaSc riptFromString:_getApkCode];
[_getApkCode release];
2.需要跟平台进行交互调用
思路:
1.制造含有一定含义的请求如:(location.href="download");
2.在方法:-(BOOL)webView:(UIWebView *)webViewshouldStartLoadWithReque
st:(NSURLRequest *)requestnavigationType:(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
functionaddDownload()
{
url='www.XXX.XXX.zip';
download(url);//调用iphone提供的js接口
addDownloadTask_ret();//获取iphone下载接口执行的下载结果,此处调的是本地的一个延迟方法
}
//获取iphone下载接口执行的下载结果
functionaddDownloadTask_ret()
{varobj=getDownloadTaskResult();//此处为iphone提供的接口,负责返回当前下载执行情况的结果if(''!=obj||undefined!=obj)
{
//调用本地的一些后续处理方法。
}
else
{
setTimeout("addDownloadTask_ret2();",1000);
}
- .js和xcode交互
- svg和js交互
- WebView和js交互
- JS 和IOS交互
- Android和JS交互
- UIWebView和js交互
- WebView和js交互
- UIWebView和Js交互
- webview和js交互
- webview和js 交互
- QWebView和js交互
- webview和js交互
- iOS和JS交互
- Android和Js交互
- Android和JS交互
- JS和AS交互
- android和js交互
- html和js交互
- android:获取手机号码和姓名实现通讯录
- 在SQL Server中修改字段类型和字段名称的存储过程
- MySql 外键约束 FOREIGN KEY REFERENCES 之 空、RESTRICT、NO ACTION、CASCADE、SET NULL 等类型分析和作用解读
- EditText设置失去焦点和重新获取焦点
- 自定义ViewGroup的一个小例子
- .js和xcode交互
- linux命令:nl命令
- Spring MVC 通过session 创建执行任务队列
- 检测是否为素数
- app跳转到设置的url汇总
- eclipse或vs在c++调试断点乱跳错位问题笔记
- 错误:IndentationError: expected an indented block
- 阿里二面(通过)
- Anddroid使用Fragment的setUserVisibleHint方法实现延时加载