日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

iOS下JS与OC互相调用(六)--WKWebView + WebViewJavascriptBridge

發(fā)布時(shí)間:2025/6/16 javascript 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS下JS与OC互相调用(六)--WKWebView + WebViewJavascriptBridge 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

iOS下JS與OC互相調(diào)用(六)--WKWebView + WebViewJavascriptBridge

轉(zhuǎn)載:原地址?https://www.jianshu.com/p/e951af9e5e74

上一篇文章介紹了UIWebView 如何通過(guò)WebViewJavascriptBridge 來(lái)實(shí)現(xiàn)JS 與OC 的互相調(diào)用,這一篇來(lái)介紹一下WKWebView 又是如何通過(guò)WebViewJavascriptBridge 來(lái)實(shí)現(xiàn)JS 與OC 的互相調(diào)用的。WKWebView 下使用WebViewJavascriptBridge與UIWebView 大同小異。主要是示例化的類不一樣,一些與webView 相關(guān)的API調(diào)用不一樣罷了。

?

WKWebView 下使用WebViewJavascriptBridge來(lái)實(shí)現(xiàn)JS 與OC 的互相調(diào)用,也是通過(guò)攔截URL來(lái)實(shí)現(xiàn)的。
下面開始介紹WKWebView 如何通過(guò)WebViewJavascriptBridge 來(lái)實(shí)現(xiàn)JS 與OC 的互相調(diào)用。
關(guān)于下載WebViewJavascriptBridge,然后導(dǎo)入工程的部分就不再贅述了。

第一步,創(chuàng)建WKWebView。

這一步,唯一需要注意的地方,就是不用再設(shè)置WKWebView?的navigationDelegate,下一步你就知道為什么了。

- (void)initWKWebView {WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];configuration.userContentController = [WKUserContentController new];WKPreferences *preferences = [WKPreferences new];preferences.javaScriptCanOpenWindowsAutomatically = YES;preferences.minimumFontSize = 30.0;configuration.preferences = preferences;self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];NSString *urlStr = [[NSBundle mainBundle] pathForResource:@"index.html" ofType:nil];NSString *localHtml = [NSString stringWithContentsOfFile:urlStr encoding:NSUTF8StringEncoding error:nil];NSURL *fileURL = [NSURL fileURLWithPath:urlStr];[self.webView loadHTMLString:localHtml baseURL:fileURL];self.webView.UIDelegate = self;[self.view addSubview:self.webView]; }

第二步,創(chuàng)建WebViewJavascriptBridge實(shí)例。

這里與上一篇文章有一些不同,WKWebView 使用的是WKWebViewJavascriptBridge,而UIWebView 使用的是WebViewJavascriptBridge。

? _webViewBridge = [WKWebViewJavascriptBridge bridgeForWebView:self.webView]; // 如果控制器里需要監(jiān)聽WKWebView 的`navigationDelegate`方法,就需要添加下面這行。 [_webViewBridge setWebViewDelegate:self];

上一步說(shuō)了不用再設(shè)置WKWebView?的navigationDelegate,那是因?yàn)樵趝-bridgeForWebView:}內(nèi)已經(jīng)將WKWebView?的navigationDelegate設(shè)置為WKWebViewJavascriptBridge的實(shí)例了。

? + (instancetype)bridgeForWebView:(WKWebView*)webView {WKWebViewJavascriptBridge* bridge = [[self alloc] init];[bridge _setupInstance:webView];[bridge reset];return bridge; }- (void) _setupInstance:(WKWebView*)webView {_webView = webView;_webView.navigationDelegate = self;_base = [[WebViewJavascriptBridgeBase alloc] init];_base.delegate = self; }

第三步,注冊(cè) js 要調(diào)用的Native 功能

為了便于維護(hù),我將所有js 要調(diào)用Native 功能放在了一個(gè)方法里添加,然后每個(gè)功能再單獨(dú)處理。
示例代碼如下:

? #pragma mark - private method - (void)registerNativeFunctions {[self registScanFunction];[self registShareFunction];[self registLocationFunction];[self regitstBGColorFunction];[self registPayFunction];[self registShakeFunction]; }// 注冊(cè)的獲取位置信息的Native 功能 - (void)registLocationFunction {[_webViewBridge registerHandler:@"locationClick" handler:^(id data, WVJBResponseCallback responseCallback) {// 獲取位置信息NSString *location = @"廣東省深圳市南山區(qū)學(xué)府路XXXX號(hào)";// 將結(jié)果返回給jsresponseCallback(location);}]; }

關(guān)于- (void)registerHandler:(NSString *)handlerName handler:(WVJBHandler)handler,我們可以這樣理解,后面的block 參數(shù)是js 要調(diào)用的Native 實(shí)現(xiàn),前面的handlerName 是這個(gè)Native 實(shí)現(xiàn)的別名。然后js 里調(diào)用handlerName 這個(gè)別名,WebViewJavascriptBridge最終會(huì)執(zhí)行block 里的Native 實(shí)現(xiàn)。

第四步,在HTML添加關(guān)鍵的js

HMTL 里在調(diào)用Native 功能之前,要先添加一個(gè)js 方法,然后主動(dòng)調(diào)用一次該方法。
要添加的方法是:

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) }

如果你看過(guò)iOS下JS與OC互相調(diào)用(一)--UIWebView 攔截URL,你就會(huì)發(fā)現(xiàn)這個(gè)方法與loadURL很像。
然后在js 中要主動(dòng)調(diào)用一次上述的setupWebViewJavascriptBridge。

setupWebViewJavascriptBridge(function(bridge) {// 這里注冊(cè)Native 要調(diào)用的js 功能。bridge.registerHandler('testJSFunction', function(data, responseCallback) {alert('JS方法被調(diào)用:'+data);responseCallback('js執(zhí)行過(guò)了');})// 如果要有其他Native 調(diào)用的js 功能,在這里按照上面的格式添加。 })

主動(dòng)調(diào)用setupWebViewJavascriptBridge有兩個(gè)目的:
1、執(zhí)行一次wvjbscheme://__BRIDGE_LOADED__請(qǐng)求。
2、注冊(cè)Native 要調(diào)用的js 功能。

執(zhí)行wvjbscheme://__BRIDGE_LOADED__,然后在WKWebView 的navigationDelegate方法中攔截該URL ,然后往HMTL中注入js。以下源碼都摘自WebViewJavascriptBridge:

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {if (webView != _webView) { return; }NSURL *url = navigationAction.request.URL;__strong typeof(_webViewDelegate) strongDelegate = _webViewDelegate;if ([_base isCorrectProcotocolScheme:url]) {// 在這里攔截wvjbscheme://__BRIDGE_LOADED__if ([_base isBridgeLoadedURL:url]) {// 這里會(huì)注入js [_base injectJavascriptFile];} else if ([_base isQueueMessageURL:url]) {[self WKFlushMessageQueue];} else {[_base logUnkownMessage:url];}decisionHandler(WKNavigationActionPolicyCancel);}if (strongDelegate && [strongDelegate respondsToSelector:@selector(webView:decidePolicyForNavigationAction:decisionHandler:)]) {[_webViewDelegate webView:webView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];} else {decisionHandler(WKNavigationActionPolicyAllow);} }- (void)injectJavascriptFile {//讀取js 內(nèi)容NSString *js = WebViewJavascriptBridge_js();// 執(zhí)行Native 的API,實(shí)現(xiàn)將js 注入 到HMTL中。[self _evaluateJavascript:js];if (self.startupMessageQueue) {NSArray* queue = self.startupMessageQueue;self.startupMessageQueue = nil;for (id queuedMessage in queue) {[self _dispatchMessage:queuedMessage];}} }

WKWebView 執(zhí)行js 的API 與 UIWebView 有些不同,WKWebView 用的是{-evaluateJavaScript: completionHandler:},這個(gè)API 不會(huì)立刻返回執(zhí)行結(jié)果,js 的執(zhí)行結(jié)果會(huì)在block 中返回。

第五步,在js 中調(diào)用 Native 功能。

講完過(guò)程,終于到了 js 調(diào)用Native 的用法了。其實(shí)非常的簡(jiǎn)單,例如我想要利用Native 獲取定位信息,那么在HTML中添加一個(gè)按鈕,onclick事件是locationClick(),按照如下實(shí)現(xiàn)即可。

function locationClick() {WebViewJavascriptBridge.callHandler('locationClick',null,function(response) {alert(response);document.getElementById("returnValue").value = response;}); }

Native 執(zhí)行完代碼,將獲取到的定位信息,通過(guò)callHandler 的第三方參數(shù),回調(diào)返回到j(luò)s 中。
response 可以是單個(gè)值,也可以是數(shù)組、鍵值對(duì)等。
當(dāng)然如果我們調(diào)用Native 的時(shí)候,沒有參數(shù)或者不需要Native 返回信息到j(luò)s 中。我們還可以這樣寫:

// 沒有參數(shù),有回調(diào)可以這樣寫 function locationClick() {WebViewJavascriptBridge.callHandler('locationClick',function(response) {alert(response);document.getElementById("returnValue").value = response;}); }// 沒有參數(shù),又不需要回調(diào)可以這樣寫 function shake() {WebViewJavascriptBridge.callHandler('shakeClick'); }

至此,JS 通過(guò)WebViewJavascriptBridge調(diào)用Native 的功能就完成了。

第六步,Native 調(diào)用 JS 功能。

Native 調(diào)用js 功能與 js 調(diào)用Native 的原理和流程一樣。
1、現(xiàn)在js 中注冊(cè),Native 要調(diào)用的功能。
2、Native 調(diào)用注冊(cè)時(shí),該功能的別名,就可以完成調(diào)用。
在js 中注冊(cè) Native 要調(diào)用的功能,同樣需要為該功能設(shè)置一個(gè)別名HandlerName。
其實(shí)這個(gè)步驟在前面介紹過(guò),代碼如下:

setupWebViewJavascriptBridge(function(bridge) {// 這里注冊(cè)Native 要調(diào)用的js 功能。bridge.registerHandler('testJSFunction', function(data, responseCallback) {alert('JS方法被調(diào)用:'+data);responseCallback('js執(zhí)行過(guò)了');})// 如果要有其他Native 調(diào)用的js 功能,在這里按照上面的格式添加。 })

上述代碼,是在JS 中注冊(cè)了一個(gè)別名叫testJSFunction的js功能,第二個(gè)參數(shù)是一個(gè)function。function里的data ,就是Native 調(diào)用該功能時(shí)傳過(guò)來(lái)的參數(shù),responseCallback是執(zhí)行完js 代碼后,通過(guò)responseCallback將必要的信息返回到Native中。

Native 調(diào)用js 里注冊(cè)的功能,示例代碼:

- (void)rightClick {// // 如果不需要參數(shù),不需要回調(diào),使用這個(gè)// [_webViewBridge callHandler:@"testJSFunction"];// // 如果需要參數(shù),不需要回調(diào),使用這個(gè)// [_webViewBridge callHandler:@"testJSFunction" data:@"一個(gè)字符串"];// 如果既需要參數(shù),又需要回調(diào),使用這個(gè)[_webViewBridge callHandler:@"testJSFunction" data:@"一個(gè)字符串" responseCallback:^(id responseData) {NSLog(@"調(diào)用完JS后的回調(diào):%@",responseData);}]; }

WKWebView 通過(guò)WebViewJavascriptBridge實(shí)現(xiàn)js 與Native 的交互,到這里就已經(jīng)完成了。
這是工程示例中的效果圖:

示例工程地址:JS_OC_WebViewJavascriptBridge

Have Fun!

轉(zhuǎn)載于:https://my.oschina.net/fadoudou/blog/1810887

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的iOS下JS与OC互相调用(六)--WKWebView + WebViewJavascriptBridge的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。