iOS 中UIWebView與WKWebView

1. UIWebView

UIWebView 適用於iOS8.0如下的系統版本 iOS原生沒有提供js直接調用OC的方式,只能經過UIWebView的UIWebViewDelegate協議方法來作攔截,並在這個方法中,根據url來調用OC方法;html

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
複製代碼
  • UIWebViewDelegate代理協議使用:
// 是否容許加載網頁,也可獲取js要打開的url,經過截取此url可與js交互
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    NSString *urlString = [[request URL] absoluteString];
    urlString = [urlString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    
    NSArray *urlComps = [urlString componentsSeparatedByString:@"://"];
    NSLog(@"urlString=%@---urlComps=%@",urlString,urlComps);
    return YES;
}
// 開始加載網頁
- (void)webViewDidStartLoad:(UIWebView *)webView {
    NSURLRequest *request = webView.request;
    NSLog(@"webViewDidStartLoad-url=%@--%@",[request URL],[request HTTPBody]);
}
// 網頁加載完成
- (void)webViewDidFinishLoad:(UIWebView *)webView {
    NSURLRequest *request = webView.request;
    NSURL *url = [request URL];
    if ([url.path isEqualToString:@"/normal.html"]) {
        NSLog(@"isEqualToString");
    }
    NSLog(@"webViewDidFinishLoad-url=%@--%@",[request URL],[request HTTPBody]);
    NSLog(@"%@",[self.webView stringByEvaluatingJavaScriptFromString:@"document.title"]);
}
// 網頁加載錯誤
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
    NSURLRequest *request = webView.request;
    NSLog(@"didFailLoadWithError-url=%@--%@",[request URL],[request HTTPBody]);
}
複製代碼

2. WKWebView

  • 引入WebKit庫 #import <WebKit/WebKit.h>
  • 在文檔中能夠看出,WKWebView的初始化方法有兩種:
- (instancetype)initWithFrame:(CGRect)frame
- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
複製代碼

咱們大多使用第一種方式,這也是文檔中默認的一種方式。git

  • WKWebView 代理 協議方法以下:
//頁面開始加載時調用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation
{
    NSLog(@"頁面開始加載時調用。 2");
}
//內容返回時調用,獲得請求內容時調用(內容開始加載) -> view的過渡動畫可在此方法中加載
- (void)webView:(WKWebView *)webView didCommitNavigation:( WKNavigation *)navigation
{
    NSLog(@"內容返回時調用,獲得請求內容時調用。 4");
}
//頁面加載完成時調用
- (void)webView:(WKWebView *)webView didFinishNavigation:( WKNavigation *)navigation
{
    NSLog(@"頁面加載完成時調用。 5");
}
//請求失敗時調用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
    NSLog(@"error1:%@",error);
}
-(void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
    NSLog(@"error2:%@",error);
}
//在請求發送以前,決定是否跳轉 -> 該方法若是不實現,系統默認跳轉。若是實現該方法,則須要設置容許跳轉,不設置則報錯。
//該方法執行在加載界面以前
//Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Completion handler passed to -[ViewController webView:decidePolicyForNavigationAction:decisionHandler:] was not called'
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
    //容許跳轉
    decisionHandler(WKNavigationActionPolicyAllow);
    
    //不容許跳轉
//    decisionHandler(WKNavigationActionPolicyCancel);
    NSLog(@"在請求發送以前,決定是否跳轉。 1");
}
//在收到響應後,決定是否跳轉(同上)
//該方法執行在內容返回以前
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
{
    //容許跳轉
    decisionHandler(WKNavigationResponsePolicyAllow);
    //不容許跳轉
//    decisionHandler(WKNavigationResponsePolicyCancel);
    NSLog(@"在收到響應後,決定是否跳轉。 3");
    
}
//接收到服務器跳轉請求以後調用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation
{
    NSLog(@"接收到服務器跳轉請求以後調用");
}
-(void)webViewWebContentProcessDidTerminate:(WKWebView *)webView
{
    NSLog(@"webViewWebContentProcessDidTerminate");
}
複製代碼

3. OC調用JS傳遞參數

  • UIWebView方法
NSString *str = [self.webview stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"postStr('%@','%@');",str1,str2]];
複製代碼
  • WKWebView方法
[self.wkWebView evaluateJavaScript:[NSString stringWithFormat:@"postStr('%@')", @"true"] completionHandler:^(id _Nullable result, NSError * _Nullable error) {
        NSLog(@"==%@----%@", result, error);
    }];
複製代碼

在須要接受參數值的js界面實現以下方法:github

function postStr(str1, str2){
    alert(str1, str2);    //接收到的值」;
    //...code
}
複製代碼

4. JS調用OC傳遞參數

js是不能執行oc代碼的,可是能夠變相的執行,js能夠將要執行的操做封裝到網絡請求裏面,而後oc攔截這個請求,獲取url裏面的字符串解析便可。(攔截URL) 好比darkangel://。方法是在html或者js中,點擊某個按鈕觸發事件時,跳轉到自定義URL Scheme構成的連接,而OC中捕獲該連接,從中解析必要的參數,實現JS到OC的一次交互。好比頁面中一個a標籤,連接以下: <a href="darkangel: smslogin?username="12323123&code=892845"">短信驗證登陸</a href="darkangel:> 在該方法中,捕獲該連接,而且返回NO(阻止本次跳轉),從而執行對應的OC方法。web

  • UIWebView方法
/*
 * 方法的返回值是BOOL值。
 * 返回YES:表示讓瀏覽器執行默認操做,好比某個a連接跳轉
 * 返回NO:表示不執行瀏覽器的默認操做,這裏由於經過url協議來判斷js執行native的操做,確定不是瀏覽器默認操做,故返回NO
 */
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
    //標準的URL包含scheme、host、port、path、query、fragment等
    NSURL *URL = request.URL;    
    if ([URL.scheme isEqualToString:@"darkangel"]) {
        if ([URL.host isEqualToString:@"smsLogin"]) {
            NSLog(@"短信驗證碼登陸,參數爲 %@", URL.query);
            return NO;
        }
    }
    return YES;
}
複製代碼
  • WKWebView方法
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    //能夠經過navigationAction.navigationType獲取跳轉類型,如新連接、後退等
    NSURL *URL = navigationAction.request.URL;
    //判斷URL是否符合自定義的URL Scheme
    if ([URL.scheme isEqualToString:@"darkangel"]) {
        //根據不一樣的業務,來執行對應的操做,且獲取參數
        if ([URL.host isEqualToString:@"smsLogin"]) {
            NSString *param = URL.query;
            NSLog(@"短信驗證碼登陸, 參數爲%@", param);
            //不容許跳轉
            decisionHandler(WKNavigationActionPolicyCancel);
            return;
        }
    }
    //容許跳轉
    decisionHandler(WKNavigationActionPolicyAllow);
    NSLog(@"%@", NSStringFromSelector(_cmd));
}
複製代碼

附:個人博客地址瀏覽器

相關文章
相關標籤/搜索