js 和 native 如何交换数据

作者: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];
  1. 然后我们也知道在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下载

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章