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下載

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