淺談WKWebView使用登颓、JS的交互


前言


WKWebView是iOS8 出來的瀏覽器控件,用來取代UIWebView.對于WKWebView與UIWebView的對比特點,這里就不過多的敘述,都算是老生常談的問題了,網上的說明也很多.近來在做Web端,需要植入移動端,并且做JS交互工作.以前寫過的JavaScript:淺談iOS與H5的交互-JavaScriptCore框架是用于UIWebView.在WKWebView并不適用了,自己做的過程中遇到一些坑,在這里總結一下,做一下記錄.


WKWebView加載本地 html文件


現(xiàn)在的項目要求就是使用存儲在本地的html文件 js文件 css文件 img圖片等文件.我使用HBuilder創(chuàng)建了一個Demo工程.里面包含了基本的文件以及圖片資源.如下所示.然后拖到Xcode工程中.

然后我們把整個Html工程文件夾導入工程中.

WKWebView 在iOS 9 有新的加載本地方法- (nullable WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL API_AVAILABLE(macosx(10.11), ios(9.0));.但是我看了網上有一些博客說- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;并不能加載本地html文件.其實兩者都能加載.只是需要把路徑寫對.第一個方法就不過多敘述了.網上有很多的博客.這里我就用第二個方法來看一下如何加載.

        NSString *path = [[[NSBundle mainBundle] bundlePath]  stringByAppendingPathComponent:@"index.html"];
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:path]];
        [_mainWebView loadRequest: request];

運行效果圖如下.



Xcode工程中 html文件 加載js文件 css文件 img文件


上面我們加載了html.可是css樣式 .img文件和js文件都沒有加載出來.那么我們該如何解決呢?(html原始加載圖如下所示.)

對于css文件搅荞、img文件 ,js文件我們只需要把html文件中的文件夾路徑刪除即可.如下所示.


???????? 注意:這里是使用的- (WKNavigation *)loadRequest:(NSURLRequest *)request;方式加載的網頁.所有如上設置即可.如果使用的是loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL或者loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL;都需要設置本地資源文件所對應的路徑! 我們只需要把資源文件所對應的路徑設置給readAccessURL 和 baseURL即可(). 例如下面所示.

//假定都在工程根目錄之下.
NSURL *baseURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
[_mainWebView loadHTMLString:[self loadHtmlString] baseURL:baseURL];


對于js文件,有時候我們發(fā)現(xiàn)我們就算如上刪除了js文件夾的路徑依然不能使用.這是為什么呢?.這里就要去檢測查看工程的設置,是否把js文件當成一個可編譯文件使用了.我們需要把它移動到資源文件中.這樣就能正常加載了.如下圖所示.


WKWebView中警告窗 確認面板 輸入框的顯示


相比于UIWebView,WKWebView對警告窗 確認面板 輸入框并不能直接顯示.是通過WKUIDelegate代理方法收到對應的回調方法.如下所示.

//接收到警告面板
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(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;

我們只需要對上面的回調方法進行實現(xiàn)即可實現(xiàn)顯示警告窗 確認面板 輸入框等需求.


WKWebView中OC方法調用JS方法


在WKWebView OC方法調用JS方法方法比較簡單.我們只需要使用如下方法即可.

- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;

看一下我寫的例子.在index.js中定義一個方法.方法內容為彈出一個警告框.代碼如下所示.

function alertAction(message) {
    alert(message);
}

然后在ViewController控制器中定義一個Button.定義它的點擊方法.代碼如下所示.

- (UIButton *)alertButton{
    
    if (_alertButton == nil) {
        _alertButton = [[UIButton alloc] initWithFrame:CGRectMake(KMainWidth*0.2, KMainHeight - 60, KMainWidth * 0.6, 40)];
        _alertButton.backgroundColor = [UIColor colorWithRed:250/255.0 green:204/255.0 blue:96/255.0 alpha:1.0];
        _alertButton.layer.cornerRadius = 6.0f;
        _alertButton.layer.masksToBounds = YES;
        _alertButton.titleLabel.font = [UIFont systemFontOfSize:16];
        [_alertButton setTitle:@"彈出彈窗" forState:UIControlStateNormal];
        [_alertButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [_alertButton addTarget:self action:@selector(alertButtonAction) forControlEvents:UIControlEventTouchUpInside];
    }
    return _alertButton;
}

- (void)alertButtonAction{
    
    [self.mainWebView evaluateJavaScript:@"alertAction('OC調用JS警告窗方法')" completionHandler:^(id _Nullable item, NSError * _Nullable error) {
        NSLog(@"alert");
    }];
    
}

因為彈窗不能直接顯示.所以我們實現(xiàn)了對應的代理方法.如下所示.

//接收到警告面板
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
    
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *action = [UIAlertAction actionWithTitle:@"ok" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();//此處的completionHandler()就是調用JS方法時,`evaluateJavaScript`方法中的completionHandler
    }];
    [alert addAction:action];
    [self presentViewController:alert animated:YES completion:nil];
}

這時候我們點擊按鈕就會調用對應的JS方法了.相比于JavaScriptCore框架還是非常簡單的.效果圖如下所示.


WKWebView中JS方法調用OC方法


上一個模塊我們看到了OC方法調用JS方法.那么JS方法調用OC方法呢?我們也只需要幾步就可以完成調用.

第一步.我們需要在WKWebView創(chuàng)建的過程中初始化添加ScriptMessageHandler.(命名自定例如:currentCookies.如下所示)

        WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
        WKUserContentController *userController = [[WKUserContentController alloc] init];
        configuration.userContentController = userController;
        _mainWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, KMainWidth, KMainHeight) configuration:configuration];
        [userController addScriptMessageHandler:self name:@"currentCookies"];

然后實現(xiàn)代理方法.監(jiān)聽JS的回調.為了查看效果,我們仍然使用彈窗的形式展示我們的回調信息.代碼如下所示.

//JS調用的OC回調方法
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
    
    if ([message.name isEqualToString:@"currentCookies"]) {
        NSString *cookiesStr = message.body;
        NSLog(@"當前的cookie為: %@", cookiesStr);
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"JS調用的OC回調方法" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *action = [UIAlertAction actionWithTitle:@"ok" style:UIAlertActionStyleCancel handler:nil];
        [alert addAction:action];
        [self presentViewController:alert animated:YES completion:nil];
    }
}

然后在Html文件中添加點擊方法.

        <div id="button_div" onclick="buttonDivAction()">
            點擊調用OC方法
        </div>

緊接著.在js文件中實現(xiàn)點擊事件.這時候要注意的是ScriptMessageHandler的名稱要與上面定義的一致.

function buttonDivAction() {
    window.webkit.messageHandlers.currentCookies.postMessage({
        "body": "buttonActionMessage"
    });
}

然后我們點擊網頁中對應的div就會出現(xiàn)對應的彈窗.效果圖如下所示.

并且控制臺打印信息如下所示.


總結


相比于UIWebView,WKWebView確實更加的方便快捷.本篇博客就到這里了.如果有任何問題,歡迎在評論區(qū)回復騷棟.感謝觀看,最后還是附上本篇博客的Demo傳送門.

JavaScriptCore框架Demo傳送門??


?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末框咙,一起剝皮案震驚了整個濱河市取具,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌扁耐,老刑警劉巖暇检,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異婉称,居然都是意外死亡块仆,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門王暗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來悔据,“玉大人,你說我怎么就攤上這事俗壹】坪梗” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵绷雏,是天一觀的道長头滔。 經常有香客問我,道長涎显,這世上最難降的妖魔是什么坤检? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮期吓,結果婚禮上早歇,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好箭跳,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布晨另。 她就那樣靜靜地躺著,像睡著了一般谱姓。 火紅的嫁衣襯著肌膚如雪拯刁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天逝段,我揣著相機與錄音垛玻,去河邊找鬼。 笑死奶躯,一個胖子當著我的面吹牛帚桩,可吹牛的內容都是我干的。 我是一名探鬼主播嘹黔,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼账嚎,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了儡蔓?” 一聲冷哼從身側響起郭蕉,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎喂江,沒想到半個月后召锈,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡获询,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年涨岁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吉嚣。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡梢薪,死狀恐怖,靈堂內的尸體忽然破棺而出尝哆,到底是詐尸還是另有隱情秉撇,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布秋泄,位于F島的核電站琐馆,受9級特大地震影響,放射性物質發(fā)生泄漏印衔。R本人自食惡果不足惜啡捶,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望奸焙。 院中可真熱鬧,春花似錦、人聲如沸与帆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽玄糟。三九已至勿她,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間阵翎,已是汗流浹背逢并。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留郭卫,地道東北人砍聊。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像贰军,于是被迫代替她去往敵國和親玻蝌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內容