Demo在這javascript
先來個最直觀的,爲何要用WKWebviewhtml
這裏分別用WKWebview 和UIWebview加載了一個百度的網頁,內存的佔用狀況以下前端
相比之下,WKWebView佔用20M,而UIWebView佔用73M,這性能提高的不僅一點點。
具體的要了解和使用 WKWebview 的,給個友情連接 劉彥瑋的技術博客
這裏主要講下 WKWebViewJavascriptBridge ,一個優秀的第三方框架java
Github地址在這裏
(https://github.com/marcuswestin/WebViewJavascriptBridge)ios
以前我也是本身封裝WK作的交互,後面偶然間看到的這個開源庫,8000+ star,果斷上手。 安卓那邊也有個相似這種的庫, 2000+ star,調用方法基本相似, 這樣 與前端的交互就能夠只寫一套代碼了,輕鬆加愉快。git
看一下目錄github
若是用UIwebview就導入WebViewJavascriptBridge。web
WKWebViewJavascriptBridge 是後面加入的,用WKWebview要導入這個頭文件微信
這裏用一個單例類用來管理交互 函數,像Cordova那種寫插件的形式,寫在一個類供JS調用,具體的能夠看Demo。app
貼一下 demo.html 的 JS 段落 ,看註釋,主要知道JS 怎麼調用 原生方法 和 註冊JS方法 供JS調用
<script type="text/javascript"> //這是必需要寫的,用來初始化一些設置 function setupWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); } if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); } window.WVJBCallbacks = [callback]; var WVJBIframe = document.createElement('iframe'); WVJBIframe.style.display = 'none'; WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__'; document.documentElement.appendChild(WVJBIframe); setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0) } //這也是固定的, OC 調JS , 須要給OC調用的函數必須寫在這個函數裏面 setupWebViewJavascriptBridge(function(bridge) { bridge.registerHandler('testJSFunction', function(data, responseCallback) { alert('JS方法被調用:'+data); responseCallback('js執行過了'); }) }) //這個 shareClick 就是 原生那邊 注入的函數 , 經過這個方法來調用原生 和傳值 //parmas 是JS 給OC的數據 , response 是 OC函數被調用以後 再 告訴JS 我被調用了 //好比微信分享,給Dic給原生 , 原生分享成功後再把結果回調給JS 進行處理 function shareClick() { var params = {'title':'測試分享的標題','content':'測試分享的內容','url':'http://www.baidu.com'}; WebViewJavascriptBridge.callHandler('shareClick',params,function(response) { console.log(response); }); } </script>
初始化
#import "WKWebViewJavascriptBridge.h" //注意是 WK 開頭的 , 若是不須要適配8.0如下的能夠直接就用WKWebview
@property WebViewJavascriptBridge* bridge;
self.bridge = [WebViewJavascriptBridge bridgeForWebView:webView];
//註冊原生方法給JS調用
- (void)registShareFunction {
[_webViewBridge registerHandler:@"shareClick" handler:^(id data, WVJBResponseCallback responseCallback) { // data 的類型與 JS中傳的參數有關 NSDictionary *tempDic = data; // 在這裏執行分享的操做 NSString *title = [tempDic objectForKey:@"title"]; NSString *content = [tempDic objectForKey:@"content"]; NSString *url = [tempDic objectForKey:@"url"]; // 將分享的結果返回到JS中 NSString *result = [NSString stringWithFormat:@"分享成功:%@,%@,%@",title,content,url]; responseCallback(result); //回調給JS }]; } //原生調用JS , JS 中先聲明testJSFunction 函數 -(void)pp_hander { //testJSFunction 是JS的方法 [_webViewBridge callHandler:@"testJSFunction" data:@"一個字符串" responseCallback:^(id responseData) { NSLog(@"調用完JS後的回調:%@",responseData); }]; }
基本用法差很少就這些,很簡潔,用起來也挺簡單,準備接入目前的項目使用。
若是不知道在模擬器怎麼看調試網頁,能夠看看淘寶前端團隊的這篇
在 iOS 模擬器中調試 Web 頁面
Safari的開發者選項,若是沒有,去偏好設置->高級->顯示開發者選項就有了
若是調用不成功,多是這些緣由
function setupWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); } if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); } window.WVJBCallbacks = [callback]; var WVJBIframe = document.createElement('iframe'); WVJBIframe.style.display = 'none'; WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__'; document.documentElement.appendChild(WVJBIframe); setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0) }
寫在JS裏的代碼這裏是不能動的,原樣貼上去就行。 以前有一次莫名其妙總是調用不了OC的方法, 後來發現是
window.WebViewJavascriptBridg 寫成了 window.WebView JavascriptBridg, 一直沒看到,在網頁端一直報找不到 WebViewJavascriptBridg這個變量,看到報錯應該能發如今定義的時候有出錯
還有一個有意思的就是我設置了 _baseWebview.navigationDelegate=self;以後居然也調用不了,JS端不走click()方法
貌似只能用 [_webViewBridge setWebViewDelegate:self];
這個方法,具體緣由再看看。