JS和OC相互調(diào)用并傳值悄雅,WebViewJavascriptBridge 的使用
在iOS開發(fā)中難免會(huì)遇到j(luò)s和oc交互驱敲,iOS8出現(xiàn)了WKWebView,WKWebView將逐步取代笨重的UIWebView宽闲。
這里就介紹使用WKWebView众眨。
不使用WebViewJavascriptBridge的JS和OC調(diào)用方法如下
首先,介紹下JS調(diào)用OC的方式容诬,JS調(diào)用OC的方法后端人員要與iOS開發(fā)人員約定好函數(shù)名稱娩梨,以及參數(shù)格式。假如有個(gè)功能览徒,應(yīng)用加載后端提供的一個(gè)網(wǎng)頁狈定,網(wǎng)頁內(nèi)需要用到地圖,調(diào)用地圖习蓬,地圖需要APP端展示而不是網(wǎng)頁提供纽什。這里就需要js調(diào)用OC類方法,調(diào)出地圖并展示躲叼。我們首先在初始化WKWebView的時(shí)候芦缰,就需要添加監(jiān)聽,監(jiān)聽js的調(diào)用枫慷,如
這里不算完涕俗,這里只是相當(dāng)于注冊(cè)了一個(gè)方法,讓js調(diào)用getLocation時(shí)變得合法神帅。
我們還需要在加載WKWebView的控制器內(nèi)實(shí)現(xiàn)一個(gè)代理,WKScriptMessageHandler協(xié)議的一個(gè)方法
接下來我們說下oc調(diào)用js.
這種也可以實(shí)現(xiàn)js和oc的交互。但項(xiàng)目開發(fā)中萝快,往往需要js和oc相互調(diào)用并傳值锻霎,比如js端想獲取設(shè)備名稱并展示出來,就需要揪漩,js調(diào)用oc的方法旋恼,oc響應(yīng)之后獲取設(shè)備名稱并立即回傳給js端以供展示用。利用上面的好像沒法實(shí)現(xiàn)奄容,其實(shí)也可以實(shí)現(xiàn)冰更,就是js端再提供一個(gè)方法,供oc端調(diào)用昂勒,并接受參數(shù)蜀细,設(shè)備名稱,那么這么一來叁怪,獲取一個(gè)設(shè)備的名稱就分成兩步了审葬,需要調(diào)用兩次函數(shù)深滚,一個(gè)是js調(diào)用oc,返回傳值的時(shí)候oc再調(diào)用js奕谭,這個(gè)有點(diǎn)煩。
所以我們可以考慮下大神的WebViewJavascriptBridge痴荐,這個(gè)神器血柳。
在podfile文件中加入?pod 'WebViewJavascriptBridge'
在用的地方引用相應(yīng)的頭文件。
在html文件中加入下段代碼
function setupWebViewJavascriptBridge(callback) {
? ? ? ? ? ? ? ? ? ? if(window.WebViewJavascriptBridge) {return callback(WebViewJavascriptBridge); }
? ? ? ? ? ? ? ? ? ? if(window.WVJBCallbacks) {return window.WVJBCallbacks.push(callback); }
? ? ? ? ? ? ? ? ? ? window.WVJBCallbacks = [callback];// 創(chuàng)建一個(gè) WVJBCallbacks 全局屬性數(shù)組生兆,并將 callback 插入到數(shù)組中难捌。
? ? ? ? ? ? ? ? ? ? var WVJBIframe = document.createElement('iframe');// 創(chuàng)建一個(gè) iframe 元素
? ? ? ? ? ? ? ? ? ? WVJBIframe.style.display ='none';
? ? ? ? ? ? ? ? ? ? WVJBIframe.src ='wvjbscheme://__BRIDGE_LOADED__';// 設(shè)置 iframe 的 src 屬性
? ? ? ? ? ? ? ? ? ? document.documentElement.appendChild(WVJBIframe);// 把 iframe 添加到當(dāng)前文導(dǎo)航上。
? ? ? ? ? ? ? ? ? ? setTimeout(function() { document.documentElement.removeChild(WVJBIframe) },0)
? ? ? ? ? ? ? ? }
? ? setupWebViewJavascriptBridge(function(bridge) {
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? });
首先還是后端和APP端開發(fā)者商議確定調(diào)用方法名稱以及傳參格式鸦难。這里拿獲取當(dāng)前設(shè)備名稱為例:
js端簡(jiǎn)單定義一個(gè)按鈕根吁,按鈕觸發(fā)方法為
function getDeviceName(){
? ? ? ? //此處第一個(gè)參數(shù)對(duì)應(yīng)的是OC方法名;
? ? ? ? //第二個(gè)參數(shù)是js端要傳給OC端的參數(shù)合蔽,不需要就傳空
? ? ? ? //第三個(gè)參數(shù)就是js端回調(diào)函數(shù)击敌,用于接收OC端傳回的值,以便于js端做其他處理
WebViewJavascriptBridge.callHandler('getDeviceName',null,function(response) {
? ? ? ? alert(response);
? ? ? ? document.getElementById("returnValue").value = response;
? ? ? ? });
? ? ? ? }
在APP端實(shí)現(xiàn)相應(yīng)的方法拴事,getDeviceName.
當(dāng)APP響應(yīng)js調(diào)用后沃斤,獲取到當(dāng)前設(shè)備名稱圣蝎,然后通過responseCallback這個(gè)block回傳給js端。
這樣就實(shí)現(xiàn)了js調(diào)用oc衡瓶,oc回傳給js徘公。
js端傳遞參數(shù)給OC端見例子。js和oc相互調(diào)用并傳值