本文介紹兩種方式實現iOS WKWebView和JS交互html
網頁很簡單,只有一個按鈕,點擊按鈕會觸發一個方法,在事件的方法中經過調用 window.webkit.messageHandlers.NativeModel.postMessage({name: 'zhangyutang', age: 12});
把消息發送給Objc。Objc中須要注入相同名稱的model:NativeModel
。網頁代碼以下html5
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>html5page-oc</title> <script> function btn1Click() { window.webkit.messageHandlers.NativeModel.postMessage({name: 'zhangyutang', age: 12}); alert("after call"); } </script> </head> <body> <input type="button" value="button c" onclick="btn1Click()"> </body> </html>
Objc代碼中在初始化WKWebView
的時候須要使用initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
方法來進行初始化。 WKWebViewConfiguration
對象須要使用調用方法 addScriptMessageHandler:name
來設置JS事件的接收處理器,addScriptMessageHandler:name
方法有兩個參數:ScriptMessageHandler
參數須要是一個實現WKScriptMessageHandler
了協議的對象;name
參數是H5頁面中調用postMessage
方法使用到的注入對象的名稱,H5頁面和原生的頁面交互使用經過該對象才能夠成功調用。web
- (WKWebView *)webView { if (!_webView) { WKWebViewConfiguration* config = [[WKWebViewConfiguration alloc] init]; config.userContentController = [WKUserContentController new]; [config.userContentController addScriptMessageHandler:self name:@"NativeModel"]; _webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config]; _webView.navigationDelegate = self; } return _webView; }
MMWebViewController
類實現了實現 WKScriptMessageHandler
協議,重寫 userContentController:didReceiveScriptMessage
回調方法 ,在該方法中處理JS的方法調用,關鍵的代碼片斷以下。ide
@interface MMWebViewController () <WKScriptMessageHandler> @end @implementation MMWebViewController #pragma mark - ......::::::: WKScriptMessageHandler :::::::...... - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { id body = message.body; NSLog(@"=== %@", body); } @end
重寫UIWebViewDelegate
的回調方法- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
,在該方法中經過判斷請求的URL的scheme
來處理特定URL,能夠處理原生頁面的跳轉、原生頁面的彈窗等業務邏輯,而後調用decisionHandler(WKNavigationActionPolicyCancel);
告訴WKWebView
不用處理這個請求,這個請求已經讓原生處理了。簡單的代碼片斷以下oop
if ([navigationAction.request.URL.scheme isEqualToString:@"plush"]) { [PTLinkUtil handleURLString:navigationAction.request.URL.absoluteString linkType:PTLinkCustomHandler roomID:0]; decisionHandler(WKNavigationActionPolicyCancel); return; } else if ([[navigationAction.request.URL.scheme lowercaseString] isEqualToString:@"lezhua"]) { if ([[navigationAction.request.URL.host lowercaseString] isEqualToString:@"home"]) { NSArray *queryItems = [NSURLComponents componentsWithString:navigationAction.request.URL.absoluteString].queryItems; for (NSInteger i = 0; i < queryItems.count; i++) { NSURLQueryItem *loopItem = queryItems[i]; if ([[loopItem.name lowercaseString] isEqualToString:@"segmentid"]) { [UIUtil showWithSegmentID:[validString(loopItem.value) integerValue]]; } } } decisionHandler(WKNavigationActionPolicyCancel); return; }