WKWebView的基础

1,589 阅读4分钟

前言

WebView:由于引入WebKit内核,可以支持对网页解析、打开文档,成为了“应用中的浏览器”,是内嵌在移动端实现前端页面的一个移动端组件。

WebView与浏览器应用(百度、谷歌等)的异同:

  • 相同点:都可以对网页进行解析,去拉取网页资源,加载网页
  • 不同点:WebView**可以使用iOS的原生控件即摄像头、打电话、录音等,还可以使用应用自身的数据以及应用功能

如何简单使用

1. webView的初始化:frame+WKWebViewConfiguration

WKWebViewConfiguration:提供webview初始化配置,常用的如下

  • preferences :网页内容的设置项,比如最小字体大小或者是否支持javaScript加载
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init]; 
WKPreferences *preference = [[WKPreferences alloc]init]; //最小字体大小 当将**javaScriptEnabled**属性设置为**NO**时,可以看到明显的效果 
preference.minimumFontSize = 0; //设置是否支持**javaScript 默认是支持的 preference.javaScriptEnabled = YES; // 在**iOS**上默认为**NO,表示是否允许不经过用户交互由**javaScript**自动打开窗口 
preference.javaScriptCanOpenWindowsAutomatically = YES; 
config.preferences = preference;
  • applicationNameForUserAgent:设置请求的User-Agent信息中应用程序名称(iOS9后可用)
config.applicationNameForUserAgent = @"ChinaDailyForiPad";
  • userContentController:这个类主要用来做nativeJS的交互管理
WeakWebViewScriptMessageDelegate *weakScriptMessageDelegate = [[WeakWebViewScriptMessageDelegate alloc] initWithDelegate:self]; //这个类主要用来做**native**与**JavaScript**的交互管理 
WKUserContentController * wkUController = [[WKUserContentController alloc] init]; //注册一个**name**为**jsToOcNoPrams**的**js**方法 
[wkUController addScriptMessageHandler:weakScriptMessageDelegate name:@"jsToOcNoPrams"]; 
[wkUController addScriptMessageHandler:weakScriptMessageDelegate name:@"jsToOcWithPrams"]; 
config.userContentController = wkUController;

简单用webView加载一个百度页面


//含有webview控件的viewcontroller

import UIKit

import WebKit 

class webViewController: UIViewController, WKUIDelegate,WKNavigationDelegate{

    var webView: WKWebView!

    override func loadView() {

        let webConfiguration = WKWebViewConfiguration()

        //用WKWebViewConfiguration来配置初始化网页视图时的属性

        webView = WKWebView(frame: .zero, configuration: webConfiguration)

        webView.uiDelegate = self

        webView.navigationDelegate = self

        view = webView

    }

    override func viewDidLoad() {

        super.viewDidLoad()

        let myURL = URL(string: "https://www.baidu.com")

        let myRequest = URLRequest(url: myURL!)

        webView.load(myRequest)

        

    }

} 

//AppDelegate

import UIKit

@main

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        // Override point for customization after application launch.

        window = UIWindow(frame: UIScreen.main.bounds)

        window?.backgroundColor = UIColor.white

        window?.rootViewController = UINavigationController(rootViewController: A())

        window?.makeKeyAndVisible()

        return true

    }

}

2.webView加载过程,可以实现WKWNavigationDelegate的代理方法对webView加载进行监控

WKNavigationDelegate:处理webview的页面加载和页面跳转


    // 页面开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
}
    // 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
    [self.progressView setProgress:0.0f animated:NO];
} 
    // 当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
}
    // 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
    [self getCookie];
}
    //提交发生错误时调用
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
    [self.progressView setProgress:0.0f animated:NO];
}  
   // 接收到服务器跳转请求即服务重定向时之后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation {
}
    // 根据WebView对于即将跳转的HTTP请求头信息和相关信息来决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    
    NSString * urlStr = navigationAction.request.URL.absoluteString;
    NSLog(@"发送跳转请求:%@",urlStr);
    //自己定义的协议头
    NSString *htmlHeadString = @"github://";
    if([urlStr hasPrefix:htmlHeadString]){
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"通过截取URL调用OC" message:@"你想前往我的Github主页?" preferredStyle:UIAlertControllerStyleAlert];
        [alertController addAction:([UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {   
        }])];
        [alertController addAction:([UIAlertAction actionWithTitle:@"打开" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            NSURL * url = [NSURL URLWithString:[urlStr stringByReplacingOccurrencesOfString:@"github://callName_?" withString:@""]];
            [[UIApplication sharedApplication] openURL:url];
        }])];
        [self presentViewController:alertController animated:YES completion:nil];
        decisionHandler(WKNavigationActionPolicyCancel);
    }else{
        decisionHandler(WKNavigationActionPolicyAllow);
    }
}
    
    // 根据客户端受到的服务器响应头以及response相关信息来决定是否可以跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
    NSString * urlStr = navigationResponse.response.URL.absoluteString;
    NSLog(@"当前跳转地址:%@",urlStr);
    //允许跳转
    decisionHandler(WKNavigationResponsePolicyAllow);
    //不允许跳转
    //decisionHandler(WKNavigationResponsePolicyCancel);
} 
    //需要响应身份验证时调用 同样在block中需要传入用户身份凭证
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
    //用户身份信息
    NSURLCredential * newCred = [[NSURLCredential alloc] initWithUser:@"user123" password:@"123" persistence:NSURLCredentialPersistenceNone];
    //为 challenge 的发送方提供 credential
    [challenge.sender useCredential:newCred forAuthenticationChallenge:challenge];
    completionHandler(NSURLSessionAuthChallengeUseCredential,newCred);
}
    //进程被终止时调用
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView{
}

3.webView的各种加载的方法

加载指定URL请求指定的web资源页面
load(_ request: URLRequest)

let myURL = URL(string: "https://hichatx.hisense.com/home/check.html")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)

加载baseURL下的指定的html页面(本地页面)
loadHTMLString(_ string: String, baseURL: URL?)

 webView.loadHTMLString("empty2", baseURL: URL(string: "http://172.20.204.42:5500"))

加载指定目录中的附加文件
loadFileURL(_ URL: URL, allowingReadAccessTo readAccessURL: URL)

//URL:文件对应的完整的**fileURL  
//allowingReadAccessTo:文件对应的目录的**fileURL
webView.loadFileURL(URL(string: "file:///Users/XXX/A/A/AppDelegate.swift")!, allowingReadAccessTo: URL(string: "file:///Users/XXX/A/A/")!)

加载二进制数据
load(_ data: Data, mimeType MIMEType: String, characterEncodingName: String, baseURL: URL)

 var path = "file:///Users/XXX/Desktop/未命名文件夹/empty2.html"
        let _data: NSData = NSData(contentsOfFile: path)!
         webView.load(_data as! Data, mimeType: "text/html", characterEncodingName: "UTF-8", baseURL: URL(string: "file:///Users/XXX/Desktop/未命名文件夹/")!)
    }