WKWebView的使用與JS交互詳細解讀

前言ios

    WKWebView 這是在iOS8.0以後增長的一個比UIWebView更加完善和強大的控件!看網上關於它的博客也是有許多的了,從各個方面總結一下這個WKWebView看網上說它主要是爲了和JS作好交互產生的,咱們也會相應的嘗試一下。就先從它基本的提及!web

一:和UIWebView相比它的不一樣處
服務器

1:和JS更好的作交互,也支持H5的一些新特性ide

2:加載進度條(下面會演示)函數

3:性能高,加載變得更快更可靠性能

二:從加載一張網頁開始
spa

1:使用這個WKWebView是要#import <WebKit/WebKit.h>
代理

2:遵照協議,WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler(最後這個協議留神一下就知道視爲JS準備的)code

3:加載百度試一下server

WKWebView * webviwe = [[WKWebView alloc]initWithFrame:self.view.bounds];
[webviwe loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.baidu.com"]]];
[self.view addSubview:webviwe];    

 

 

三:說說加載進度條

       這個是利用KVO模式寫的,WKWebView有一個  estimatedProgress 屬性,利用它來監聽加載的進度,下面的進度打印出來了,但具體的進度條就沒有寫出來,大家能夠本身寫一個 UIProgressView 放在導航欄的下面。

 // estimatedProgress  WKWebView 這個屬性添加觀察者
 [webviwe addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];    

 

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    if (object == webviwe && [keyPath isEqualToString:@"estimatedProgress"] ) {
        // 這裏就不寫進度條了,把加載的進度打印出來,進度條能夠本身加上去!
        CGFloat newProgress = [[change objectForKey:NSKeyValueChangeNewKey] floatValue];
        NSLog(@"%f",newProgress);  
    }
}

看看打印的進度信息 

2016-08-11 14:44:17.237 RaectiveCocoaTest[21054:252565] 頁面開始加載

2016-08-11 14:44:17.724 RaectiveCocoaTest[21054:252565] 0.300000

2016-08-11 14:44:17.726 RaectiveCocoaTest[21054:252565] 內容正在加載當中

2016-08-11 14:44:18.000 RaectiveCocoaTest[21054:252565] 0.719984

2016-08-11 14:44:18.196 RaectiveCocoaTest[21054:252565] 1.000000

2016-08-11 14:44:18.196 RaectiveCocoaTest[21054:252565] 頁面加載完成

四:詳細的方法使用說明以及註釋

詳解 WKNavigationDelegate 代理方法,咱們把它的代理方法使用代碼以及注意點全都寫出來,注意看下面的註釋!

 

#pragma mark - WKNavigationDelegate
// 頁面加載開始  Provisional臨時的
-(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
{
    NSLog(@"頁面開始加載");   
}
// 加載內容
-(void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation
{
    NSLog(@"內容正在加載當中");
}
// 頁面加載完成
-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
    NSLog(@"頁面加載完成");
}
//  頁面加載失敗
-(void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
    NSLog(@"頁面加載失敗");
}
// 接收到服務器從新配置請求以後再執行
-(void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation
{
    
}
// API是根據WebView對於即將跳轉的HTTP請求頭信息和相關信息來決定是否跳轉
-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{   
    NSURLRequest * request = navigationAction.request;
    NSLog(@"%@",request.URL.absoluteString);
    
    // 判斷請求頭是不是 https://www.baidu.com 若是是就不在請求加載跳轉
    WKNavigationActionPolicy  actionPolicy = WKNavigationActionPolicyAllow;
    if ([request.URL.absoluteString hasPrefix:@"https://www.baidu.com"]) {
        
        actionPolicy = WKNavigationActionPolicyCancel;
        
    }
    // 必須這樣執行,否則會崩
    decisionHandler(actionPolicy);
}
/**
 *   
 要是容許跳轉,看下面的打印內容,注意加載的順序!和下面的方法進行比較,區分它們的不一樣之處
 2016-08-11 13:55:12.628 RaectiveCocoaTest[18155:211964] https://www.baidu.com/
 2016-08-11 13:55:12.629 RaectiveCocoaTest[18155:211964] 頁面開始加載
 2016-08-11 13:55:13.725 RaectiveCocoaTest[18155:211964] 內容正在加載當中
 2016-08-11 13:55:14.681 RaectiveCocoaTest[18155:211964] 頁面加載完成
 *
 */
// API是根據客戶端受到的服務器響應頭以及response相關信息來決定是否能夠跳轉
-(void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
    NSLog(@"%@",navigationResponse.response);
    /**
     *  判斷響應的數據裏面的URL是https://www.baidu.com/開頭的,要是就不讓它加載跳轉
     */
    WKNavigationResponsePolicy responsePolicy = WKNavigationResponsePolicyAllow;
    if ([navigationResponse.response.URL.absoluteString hasPrefix:@"https://www.baidu.com/"]) {
        
        responsePolicy = WKNavigationResponsePolicyCancel;
    }
    decisionHandler(responsePolicy);
}
/**
 *  
 響應返回的的URL包含了https://www.baidu.com/,因此頁面是不能被加載的,要是能加載就有下面的打印信息,注意和上面方法的區分對比!
 2016-08-11 13:53:38.392 RaectiveCocoaTest[17961:209778] 頁面開始加載
 2016-08-11 13:53:38.675 RaectiveCocoaTest[17961:209778] https://www.baidu.com/
 2016-08-11 13:53:38.678 RaectiveCocoaTest[17961:209778] 內容正在加載當中
 2016-08-11 13:53:38.936 RaectiveCocoaTest[17961:209778] 頁面加載完成
 */

 五:說說WKUIDelegate和JS的簡單交互 

先看看 WKUIDelegate裏面的代理方法都是用來作什麼的,咱們一個一個的解釋這幾個代理方法;

// 建立方法,這個就不在多說了,重點放在下面幾個
-(nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
{
    return nil;
}

// ios 9 以後纔有的方法
-(void)webViewDidClose:(WKWebView *)webView
{
    
}

下面這三個方法根據方法前面的字面意思就能區分記住!

runJavaScriptAlert 方法注意點

1.在JS端調用alert函數時,會觸發此代理方法。

2.JS端調用alert時所傳的數據能夠經過message,打印message信息讀取出JS端給你的信息。

3.在原生獲得結果後,須要回調給JS,經過completionHandler 回調給JS

4.completionHandler 回調的參數和返回值都是空

/**
下面這三個方法根據前面的字面意思就能區分記住!
 */
// runJavaScriptAlert
// 在JS端調用alert函數時,會觸發此代理方法。
// JS端調用alert時所傳的數據能夠經過message,打印message信息讀取出JS端給你的信息。
// 在原生獲得結果後,須要回調給JS,經過completionHandler 回調給JS
// completionHandler 回調的參數和返回值都是空
-(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
{

    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"alert"message:@"JS調用alert"preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:@"肯定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        
    }]];
    
    [self presentViewController:alert animated:YES completion:NULL];
    NSLog(@"%@", message);
    
}

runJavaScriptTextInput 注意點

1.要求用戶輸入一段文字

3.在原生輸入獲得文本內容後,經過completionHandler回調給JS

4.你們注意這個回調的completionHandler參數是字符串 

// runJavaScriptTextInput
// 要求用戶輸入一段文本
// 在原生輸入獲得文本內容後,經過completionHandler回調給JS 你們注意這個回調的completionHandler參數是字符串
-(void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler
{

}

runJavaScriptConfirmPane(ConfirmPane字面意思是確認框)

1.JS端調用confirm函數時,會觸發此方法

2.經過message能夠拿到JS端所傳給咱們數據

3.在iOS端顯示原生alert獲得YES/NO後,經過completionHandler回調給JS端

4.注意這個completionHandler回調的參數是BOOL類型的

-(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler
{
    
}

要有什麼問題或者發現錯誤的地方,及時留言聯繫我,立馬改正! 

相關文章
相關標籤/搜索