WKWebView基本使用

Starting in iOS 8.0 and OS X 10.10, use WKWebView to add web content to your app. Do not use UIWebView or WebView.

WKWebView新特性

  • 占用內(nèi)存變少了(模擬器加載百度首頁,WKWebView占用22M,UIWebView占用65M)
  • 更多的支持HTML5的特性
  • 官方宣稱高達(dá)60fps的滾動(dòng)刷新率以及內(nèi)置手勢
  • 和Safari相同的JavaScript引擎

WKWebView生命周期和跳轉(zhuǎn)代理

#pragma mark - WKNavigationDelegate
// 頁面開始加載時(shí)調(diào)用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
    NSLog(@"頁面開始加載:%s",__FUNCTION__);
}
// 當(dāng)內(nèi)容開始返回時(shí)調(diào)用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
    NSLog(@"內(nèi)容開始返回:%s",__FUNCTION__);
}
// 頁面加載完成之后調(diào)用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
    NSLog(@"頁面加載完成:%s",__FUNCTION__);
}

// 頁面加載失敗時(shí)調(diào)用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    NSLog(@"%@",error.debugDescription);
}

// 接收到服務(wù)器跳轉(zhuǎn)請求之后調(diào)用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{
    
}
// 在收到響應(yīng)后,決定是否跳轉(zhuǎn)
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
    
    NSLog(@"%@",navigationResponse.response.URL.absoluteString);
    //允許跳轉(zhuǎn)
    decisionHandler(WKNavigationResponsePolicyAllow);
    //不允許跳轉(zhuǎn)
    //decisionHandler(WKNavigationResponsePolicyCancel);
}
// 在發(fā)送請求之前,決定是否跳轉(zhuǎn)
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
    
    NSLog(@"%@",navigationAction.request.URL.absoluteString);
    //允許跳轉(zhuǎn)
    decisionHandler(WKNavigationActionPolicyAllow);
    //不允許跳轉(zhuǎn)
    //decisionHandler(WKNavigationActionPolicyCancel);
}

前進(jìn) 后退 刷新 進(jìn)度條

//前進(jìn)
webView.goBack()
//后退
webView.goForward()
//刷新
let request = NSURLRequest(URL:webView.URL!)
webView.loadRequest(request)

//監(jiān)聽是否可以前進(jìn)后退,修改btn.enable屬性
webView.addObserver(self, forKeyPath: "loading", options: .New, context: nil)
//監(jiān)聽加載進(jìn)度
webView.addObserver(self, forKeyPath: "estimatedProgress", options: .New, context: nil)

//重寫self的kvo方法
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
    if (keyPath == "loading") {
        gobackBtn.enabled = webView.canGoBack
        forwardBtn.enabled = webView.canGoForward
    }
    if (keyPath == "estimatedProgress") {
        //progress是UIProgressView
        progress.hidden = webView.estimatedProgress==1
        progress.setProgress(Float(webView.estimatedProgress), animated: true)
    }
}

JS中alert攔截

在WKWebview中,js的alert是不會(huì)出現(xiàn)任何內(nèi)容的,你必須重寫WKUIDelegate委托的runJavaScriptAlertPanelWithMessage message方法,自己處理alert。類似的還有Confirm和prompt,這里我只以alert為例。

// 輸入框
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler{
    completionHandler(@"hello");
}
// 確認(rèn)框
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler{
    completionHandler(YES);
}
// 警告框
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:webView.title message:message preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
    }]];
    [self presentViewController:alert animated:YES completion:nil];
}

app調(diào)用js方法

WKWebView調(diào)用js方法和UIWebView類似,一個(gè)是evaluateJavaScript,一個(gè)是stringByEvaluatingJavaScriptFromString。獲取返回值的方式不同,WKWebView用的是回調(diào)函數(shù)獲取返回值。

 //直接調(diào)用js
    webView.evaluateJavaScript("hello()", completionHandler: nil)
    //調(diào)用js帶參數(shù)
    webView.evaluateJavaScript("hello('ls')", completionHandler: nil)
    //調(diào)用js獲取返回值
    webView.evaluateJavaScript("getName()") { (any,error) -> Void in
        NSLog("%@", any as! String)
    }

js調(diào)用app方法

1:注冊handler需要在webView初始化之前;

   //配置環(huán)境
    WKWebViewConfiguration *conf = [[WKWebViewConfiguration alloc] init];
    userContentController = [[WKUserContentController alloc] init];
    conf.userContentController = userContentController;
    
    // 注冊方法
    [userContentController addScriptMessageHandler:self name:@"webViewHandle"];
    
    // 初始化
    self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:conf];

2:處理handler委托。ViewController實(shí)現(xiàn)WKScriptMessageHandler委托的方法

// 使用safari模擬器調(diào)試
// 前端需要用 window.webkit.messageHandlers.注冊的方法名.postMessage({body:傳輸?shù)臄?shù)據(jù)} 來給native發(fā)送消息
// window.webkit.messageHandlers.webViewHandle.postMessage("Hello WebKit!")
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    NSLog(@"%@ -- %@",message.name, message.body);
}

3:通過 window.webkit.messageHandlers.webViewApp找到之前注冊的handler對象,然后調(diào)用postMessage方法把數(shù)據(jù)傳到app,app通過上一步的方法從message.body中解析方法名和參數(shù)

// 只能傳一個(gè)參數(shù) 可以用json或字典組裝參數(shù),在app里去解析
var message = 'Hello WebKit!'  
   window.webkit.messageHandlers.webViewApp.postMessage(message);

參考文章

這里僅僅簡要記錄了基本用法。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 隨說 : 最近有個(gè)需求,是將公司的一個(gè)內(nèi)網(wǎng)的頁面嵌套在app中作為一個(gè)模塊.這不是很簡單的webView請求一下就...
    travin閱讀 31,088評論 26 73
  • 為何使用WKWebView App開發(fā)過程中不可避免的會(huì)用到加載網(wǎng)頁,從iOS2開始,我們一直使用的是UIWebV...
    辰牧殤閱讀 1,057評論 0 1
  • 前言 關(guān)于UIWebView的介紹,相信看過上文的小伙伴們,已經(jīng)大概清楚了吧,如果有問題,歡迎提問。 本文是本系列...
    CoderLF閱讀 9,368評論 2 12
  • 現(xiàn)在大部分的app只支持iOS8以上的系統(tǒng)了,在接入H5時(shí)可以只管最新的WKWebView了。 WKWebView...
    L小杰閱讀 17,436評論 6 33
  • WKWebView 是蘋果在 WWDC 2014 上推出的新一代 webView 組件,用以替代 UIKit 中笨...
    Aiana閱讀 4,834評論 1 8

友情鏈接更多精彩內(nèi)容