您的位置:首页 > Web前端 > JavaScript

js 和 native 如何交换数据

2016-06-22 18:41 459 查看
作者:Love@YR

链接:http://blog.csdn.net/jingqiu880905/article/details/51736367

请尊重原创,谢谢!

关于js和native的交互文章已经很多了,推荐看下:

http://blog.devtang.com/2012/03/24/talk-about-uiwebview-and-phonegap/

其中我们知道的如:

1. 如何发起一个request

以UIWebView为例:

NSMutableURLRequest *mReq = [NSMutableURLRequest requestWithURL:theURLToLoad];
[self.webView loadRequest:mReq];


或者加载本地的:

NSString * path = [[NSBundle mainBundle] bundlePath];
NSURL * baseURL = [NSURL fileURLWithPath:path];
NSString * htmlFile = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
NSString * htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:(NSUTF8StringEncoding) error:nil];
[self.webView loadHTMLString:htmlString baseURL:baseURL];


然后我们也知道在webview的delegate方法:

webView:shouldStartLoadWithRequest:navigationType:

那里去截获js。

一直不明白的是这个方法是如何截获到js的。

直到看到上述文章

贴下代码:

// Javascript 语言
// 通知 iPhone UIWebView 加载 url 对应的资源
// url 的格式为: gap:something
function loadURL(url) {
var iFrame;
iFrame = document.createElement("iframe");
iFrame.setAttribute("src", url);
iFrame.setAttribute("style", "display:none;");
iFrame.setAttribute("height", "0px");//可不要
iFrame.setAttribute("width", "0px");//可不要
iFrame.setAttribute("frameborder", "0");//可不要
document.body.appendChild(iFrame);
// 发起请求后这个 iFrame 就没用了,所以把它从 dom 上移除掉
setTimeout(function(){
iFrame.parentNode.removeChild(iFrame);
iFrame = null;
},200)
}//这里最好是加到timeOut方法里
}


然而js基础薄弱不懂为啥这几句代码就让UIWebView 加载了 url 对应的资源

那么现在我想知道js和native如何交换数据的。

下载https://github.com/tangqiaoboy/UIWebViewSample 的代码,然后做如下改动:

index.html那边:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8">
<script language="javascript">
function loadURL(url) {
var iFrame;
iFrame = document.createElement("iframe");
iFrame.setAttribute("src", url);
iFrame.setAttribute("style", "display:none;");
iFrame.setAttribute("height", "0px");
iFrame.setAttribute("width", "0px");
iFrame.setAttribute("frameborder", "0");
document.body.appendChild(iFrame);
// 发起请求后这个iFrame就没用了,所以把它从dom上移除掉
iFrame.parentNode.removeChild(iFrame);
iFrame = null;
}
function check(){
var params = {
param:"abc",//h5传给native的参数
callbackMethod:"nativeCallback"//native那边事件处理完之后的h5回调方法
}

var urlstr = "jean://h5/plugin?jsparam="+JSON.stringify(params);
alert('urlstr is '+urlstr);
loadURL(urlstr);
}

//call back method
function nativeCallback(callbackParam){
alert('the param passed from native is: '+callbackParam);
callbackfun(function(){
alert('success~~~');
},function(){
alert('failed!!!');
});
}

function callbackfun(c1,c2){
var success=true;
alert('start to call the callback');
if(success) c1();
else c2();
}
</script>
</head>

<body>
<h1>这是一段内容</h1>
<input type="button" value="测试" onclick="check()" />
</body>
</html>


ViewController.m 里

#define kURLJSParamTagKey @"jsparam"


webView:shouldStartLoadWithRequest:navigationType:那边:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSURL * url = [request URL];
if ([[url scheme] isEqualToString:@"jean"]) {

NSString *urlStr=[url query];//拿到查询字符串
NSString *paramString = [urlStr substringFromIndex:[kURLJSParamTagKey length] + 1];//拿到jsparam=后面的内容
paramString =[paramString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];//URL解码

NSDictionary *urlParamMap = [paramString  objectFromJSONString];//string转换成dictionary,需引入jsonkit
NSString *param = [urlParamMap objectForKey:@"param"];//拿到h5传给native的数据
NSLog(@"the data passed from h5 to native is %@",param);

NSString *callbackMethod = [urlParamMap objectForKey:@"callbackMethod"];//拿到callbackMethod的名字
NSString *callbackParam=@"88888888";//你想回传给h5的数据

NSString * js =[NSString stringWithFormat:@"%@('%@')",callbackMethod,callbackParam];//js字串
[self.webView stringByEvaluatingJavaScriptFromString:js];//执行js

//        UIAlertView * alertView = [[[UIAlertView alloc] initWithTitle:@"test" message:[url absoluteString] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];
//        [alertView show];
return NO;
}

return YES;
}


即可。这里还需要把JSONKit库加进来。

在js 代码那边可以设置要传给native的数据,设置native做完事情之后想让js回调的方法。

在native代码那边可以设置传给js的数据。

这样就做到了交换数据的功能,且native这边的开发人员不再需要知道回调方法是啥。

demo下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: