前言
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:这个类主要用来做native与JS的交互管理
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/未命名文件夹/")!)
}