ios下OC與JS交互之WKWebView
上一篇文章我們使用了JavaScriptCore框架重寫了之前的示例,iOS8蘋果偏愛HTML5,重構了UIWebVIew,給我們帶來了WKWebView,使其性能、穩(wěn)定性、功能大幅度提升,也更好的支持了HTML5的新特性。這篇文章就們就拿WKWebView來小試牛刀
一、WKWebView Framework
WKWebView的14個類與3個協(xié)議:
WKBackForwardList: 之前訪問過的 web 頁面的列表,可以通過后退和前進動作來訪問到。
WKBackForwardListItem: webview 中后退列表里的某一個網(wǎng)頁。
WKFrameInfo: 包含一個網(wǎng)頁的布局信息。
WKNavigation: 包含一個網(wǎng)頁的加載進度信息。
WKNavigationAction: 包含可能讓網(wǎng)頁導航變化的信息,用于判斷是否做出導航變化。
WKNavigationResponse: 包含可能讓網(wǎng)頁導航變化的返回內容信息,用于判斷是否做出導航變化。
WKPreferences: 概括一個 webview 的偏好設置。
WKProcessPool: 表示一個 web 內容加載池。
WKUserContentController: 提供使用 JavaScript post 信息和注射 script 的方法。
WKScriptMessage: 包含網(wǎng)頁發(fā)出的信息。
WKUserScript: 表示可以被網(wǎng)頁接受的用戶腳本。
WKWebViewConfiguration: 初始化 webview 的設置。
WKWindowFeatures: 指定加載新網(wǎng)頁時的窗口屬性。
WKWebsiteDataStore: 包含網(wǎng)頁數(shù)據(jù)存儲和查找。
WKNavigationDelegate: 提供了追蹤主窗口網(wǎng)頁加載過程和判斷主窗口和子窗口是否進行頁面加載新頁面的相關方法。
WKUIDelegate: 提供用原生控件顯示網(wǎng)頁的方法回調。
WKScriptMessageHandler: 提供從網(wǎng)頁中收消息的回調方法。
二、WKWebView中的三個代理方法
1. WKNavigationDelegate
該代理提供的方法,可以用來追蹤加載過程(頁面開始加載、加載完成、加載失?。Q定是否執(zhí)行跳轉。
// 頁面開始加載時調用 - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation; // 當內容開始返回時調用 - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation; // 頁面加載完成之后調用 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation; // 頁面加載失敗時調用 - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation;
頁面跳轉的代理方法有三種,分為(收到跳轉與決定是否跳轉兩種)
// 接收到服務器跳轉請求之后調用 - (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation; // 在收到響應后,決定是否跳轉 - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler; // 在發(fā)送請求之前,決定是否跳轉 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
2. WKUIDelegate
創(chuàng)建一個新的WKWebView
// 創(chuàng)建一個新的WebView - (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures;
剩下三個代理方法全都是與界面彈出提示框相關的,針對于web界面的三種提示框(警告框、確認框、輸入框)分別對應三種代理方法。
// 界面彈出警告框 - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(void (^)())completionHandler; // 界面彈出確認框 - (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler; // 界面彈出輸入框 - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler;
3. WKScriptMessageHandler
這個協(xié)議中包含一個必須實現(xiàn)的方法,這個方法是native與web端交互的關鍵,它可以直接將接收到的JS腳本轉為OC或Swift對象。
// 從web界面中接收到一個腳本時調用 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;
三、使用WKWebView重寫
這里我們和之前的界面做了一點改動,之前OC調用JS的時候是進行彈框處理,這里我在寫的時候,很郁悶,方法可以調用過去,但是唯獨js的alert方法調用沒有效果,所以這里采用了輸出到div的形式,并增加了一個clear按鈕
WKWebView不支持nib文件,所以這里需要使用代碼初始化并加載WebView
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init]; config.preferences.minimumFontSize = 18; self.wkWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height/2) configuration:config]; [self.view addSubview:self.wkWebView]; NSString *filePath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"]; NSURL *baseURL = [[NSBundle mainBundle] bundleURL]; [self.wkWebView loadHTMLString:[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil] baseURL:baseURL];
OC端:
//1. JS調用OC 添加處理腳本 [userCC addScriptMessageHandler:self name:@"showMobile"]; [userCC addScriptMessageHandler:self name:@"showName"]; [userCC addScriptMessageHandler:self name:@"showSendMsg"]; // 在代理方法中處理對應事件 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { NSLog(@"%@",NSStringFromSelector(_cmd)); NSLog(@"%@",message.body); if ([message.name isEqualToString:@"showMobile"]) { [self showMsg:@"我是下面的小紅 手機號是:18870707070"]; } if ([message.name isEqualToString:@"showName"]) { NSString *info = [NSString stringWithFormat:@"你好 %@, 很高興見到你",message.body]; [self showMsg:info]; } if ([message.name isEqualToString:@"showSendMsg"]) { NSArray *array = message.body; NSString *info = [NSString stringWithFormat:@"這是我的手機號: %@, %@ !!",array.firstObject,array.lastObject]; [self showMsg:info]; } } // 2. native調用js - (IBAction)btnClick:(UIButton *)sender { if (!self.wkWebView.loading) { if (sender.tag == 123) { [self.wkWebView evaluateJavaScript:@"alertMobile()" completionHandler:^(id _Nullable response, NSError * _Nullable error) { //TODO NSLog(@"%@ %@",response,error); }]; } if (sender.tag == 234) { [self.wkWebView evaluateJavaScript:@"alertName('小紅')" completionHandler:nil]; } if (sender.tag == 345) { [self.wkWebView evaluateJavaScript:@"alertSendMsg('18870707070','周末爬山真是件愉快的事情')" completionHandler:nil]; } } else { NSLog(@"the view is currently loading content"); } }
JS端:
function clear() { document.getElementById('mobile').innerHTML = '' document.getElementById('name').innerHTML = '' document.getElementById('msg').innerHTML = '' } //OC調用JS的方法列表 function alertMobile() { //這里已經(jīng)調用過來了 但是搞不明白為什么alert方法沒有響應 //alert('我是上面的小黃 手機號是:13300001111') document.getElementById('mobile').innerHTML = '我是上面的小黃 手機號是:13300001111' } function alertName(msg) { //alert('你好 ' + msg + ', 我也很高興見到你') document.getElementById('name').innerHTML = '你好 ' + msg + ', 我也很高興見到你' } function alertSendMsg(num,msg) { //window.alert('這是我的手機號:' + num + ',' + msg + '!!') document.getElementById('msg').innerHTML = '這是我的手機號:' + num + ',' + msg + '!!' } //JS響應方法列表 function btnClick1() { window.webkit.messageHandlers.showMobile.postMessage(null) } function btnClick2() { window.webkit.messageHandlers.showName.postMessage('xiao黃') } function btnClick3() { window.webkit.messageHandlers.showSendMsg.postMessage(['13300001111', 'Go Climbing This Weekend !!!']) }
四、后記
至此,整個系列的示例已完成,過程中收貨頗豐。每篇文章都會對知識點進行總結,在文章末尾給出示例DEMO的地址。
示例DEMO:OC-JS-WKWebView_jb51.rar
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
iOS UITextField、UITextView只限輸入中文、英文、數(shù)字及實時限制字符個數(shù)的封裝實現(xiàn)代碼
這篇文章主要介紹了 iOS UITextField、UITextView只限輸入中文、英文、數(shù)字及實時限制字符個數(shù)封裝實現(xiàn)的相關資料,需要的朋友可以參考下2016-12-12iOS實現(xiàn)卡片式滾動效果 iOS實現(xiàn)電影選片效果
這篇文章主要為大家詳細介紹了iOS實現(xiàn)卡片式滾動效果,實現(xiàn)電影選片效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-02-02IOS TextFiled與TextView 鍵盤的收起以及處理鍵盤遮擋
這篇文章主要介紹了IOS TextFiled與TextView 鍵盤的收起以及處理鍵盤遮擋的相關資料,需要的朋友可以參考下2016-12-12詳解iOS開發(fā)中解析JSON中的boolean類型的數(shù)據(jù)遇到的問題
這篇文章主要介紹了詳解iOS開發(fā)中解析JSON中的boolean類型的數(shù)據(jù)遇到的問題,具有一定的參考價值,有興趣的可以了解一下。2016-12-12