最近项目开发过程中经常碰到使用UIWebView和JavaScript进行数据交互的操作。
研究了一下,有些体会,分享出来大家多交流交流。
这样的数据交互一般分为有两种:
1、JS向客户端请求本地操作 2、客户端向JS传递参数(数据)
首先第一种,js向客户端请求本地操作:
这种操作的实现主要通过UIWebView的delegate方法来实现
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
在方法中通过webView加载的url来判断是否需要进行处理,首先和服务器端定好相关的协议,比如,协议格式如下:
XX::command:key1=value1&key2=value2......
上边协议意义解释:XX为协议名 command时命令名 后边的是参数的键值对,多个以&连接
比如本次请求的请求串是:
test::login:
那么相应的js代码写法就是:
function loginAction(){
var url = "test::login:";
document.location = url;
}
相应的IOS端的代码是:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
// 处理事件
NSString *requestString = [[request URL] absoluteString];
NSArray *components = [requestString componentsSeparatedByString:@"::"];
if (components != nil && [components count] > 0) {
NSString *pocotol = [components objectAtIndex:0];
if ([pocotol isEqualToString:@"test"]) {
NSString *commandStr = [components objectAtIndex:1];
NSArray *commandArray = [commandStr componentsSeparatedByString:@":"];
if (commandArray != nil && [commandArray count] > 0) {
NSString *command = [commandArray objectAtIndex:0];
if ([command isEqualToString:@"login"]) {
//进行本地操作
}
}
return NO;
}
}
return YES;
}
接下来介绍第二种:客户端向js传递参数
博主遇到的情况如下:
userinfo = CustomJS.getUserInfo(); userinfo = $.parseJSON(userinfo);
这是js代码中需要调用的客户端的代码,请看安卓端的写法
addJavascriptInterface(new CustomJs(), 'CustomJS');
代码可以看出,通过安卓API定义的方法,安卓端向js传递了一个CustomJS类的对象,
第二个参数字符串类型是在js中使用是引用的写法,如果第二个参数传'abc',
那么
userinfo = CustomJS.getUserInfo();需要写做
userinfo = abc.getUserInfo();
但是在OC中是没有这样的方法的,并且向JS中传OC对象的做法网上没有找到相关介绍的文章,有些论坛说这个在私有API中可以实现,当然我们开发中不能使用,那么要如何做呢?在UIWebView的介绍中只有一个方法能与js进行交互
- (NSString *)stringByEvaluatingJavaScriptFormString:(NSString *)script;
下边介绍如何通过这个方法完成与安卓一样的功能:
通过客户端向js传递一个带参数的功能,可以在客户端向页面中注入一个js方法,如下:
NSString *js = [NSString stringWithFormat:@"function getAction(){return '%@'}",@"value"];
[webView stringByEvaluatingJavaScriptFromString:js];
在js代码中调用window.getAction()即可,但是安卓的API提供的方法
addJavascriptInterface(new CustomJs(), 'CustomJS');有两个参数,
为了使IOS与安卓调用保持一致,需要对js进行修改,如下:
#define JsStr @"var CustomJS = {}; (function initialize() { CustomJS.getUserInfo = function () { return '%@';};})(); "
NSString *json = [JsonData jsonStringForObj:dict];//此处为将参数转换为json字符串
NSString *js = [NSString stringWithFormat:JsStr, json];//组装好的js方法
[webView stringByEvaluatingJavaScriptFromString:js];//注入web页面
大概意思就是在js中调用CustomJS.getUserInfo方法的时候将此方法导向另外一个方法返回需要的参数,这样在IOS中也能和安卓实现一样的调用功能了
特别感谢提供思路的朋友http://blog.sina.com.cn/s/blog_735065f90101m93l.html