网上很多这方面的资料都写的很好的,例如下面的这个地址:OC: WKWebView详解 然后自己也总结了一些自己再开发中遇到的问题,顺便介绍一下WKWebView的属性和方法
在性能、稳定性、功能方面有很大提升(最直观的体现就是加载网页是占用的内存);
允许Javascript的Nitro库加载并使用(UIWebView中限制);
支持了更多的HTML5特性;
高达60fps的滚动刷新率以及内置手势;
将UIWebViewDelegate与UIWebView重构成了14类与3个协议 查看苹果官方文档;
WebKit框架中最核心的类应该属于WKWebView了,这个类专门用来渲染网页视图,其他类和协议都将基于它和服务于它。
类 | 说明 |
---|---|
WKWebView | 网页的渲染与展示,通过WKWebViewConfiguration可以进行自定义配置 |
WKWebViewConfiguration | 这个类专门用来配置WKWebView |
WKPreference | 这个类用来进行相关webView设置 |
WKProcessPool | 这个类用来配置进程池,与网页视图的资源共享有关 |
WKUserContentController | 这个类主要用来做native与Javascript的交互管理 |
WKUserScript | 用于进行Javascript注入 |
WKScriptMessageHandler | 这个类专门用来处理Javascript调用native的方法 |
WKNavigationDelegate | 网页跳转间的导航管理协议,这个协议可以监听网页的活动 |
WKNavigationAction | 网页某个活动的示例化对象 |
WKUIDelegate | 用于交互处理Javascript中的一些弹出框 |
WKBackForwardList | 堆栈管理的网页列表 |
WKBackForwardListItem | 每个网页节点对象 |
属性 | 说明 |
---|---|
configuration | webView的自定义配置 |
navigationDelegate | 导航代理 |
UIDelegate | UI代理 |
backForwardList | 访问过网页历史列表 |
title | 网页的标题 |
URL | 网页的URL地址 |
loading | 网页是否正在加载 |
estimatedProgress | 加载的进度 范围为[0, 1] |
hasOnlySecureContent | 网页链接是否安全 |
serverTrust | 证书服务 |
canGoBack | 是否可以返回 |
canGoForward | 是否可以前进 |
/// 自定义初始化webView
- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
/// url加载webView视图
- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;
/// 文件加载webView视图
- (nullable WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL API_AVAILABLE(macosx(10.11), ios(9.0));
/// HTMLString字符串加载webView视图
- (nullable WKNavigation *)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;
/// NSData数据加载webView视图
- (nullable WKNavigation *)loadData:(NSData *)data MIMEType:(NSString *)MIMEType characterEncodingName:(NSString *)characterEncodingName baseURL:(NSURL *)baseURL API_AVAILABLE(macosx(10.11), ios(9.0));
/// 返回上一个网页节点
- (nullable WKNavigation *)goToBackForwardListItem:(WKBackForwardListItem *)item;
/// 返回到上一个网页
- (nullable WKNavigation *)goBack;
/// 前进到下一个网页
- (nullable WKNavigation *)goForward;
/// 重新加载
- (nullable WKNavigation *)reload;
/// 忽略缓存 重新加载
- (nullable WKNavigation *)reloadFromOrigin;
/// 停止加载
- (void)stopLoading;
/// 执行Javascript
- (void)evaluateJavascript:(NSString *)JavascriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;
/// 据设置的缩放因子来缩放页面,并居中显示结果在指定的点
- (void)setMagnification:(CGFloat)magnification centeredAtPoint:(CGPoint)point;
简单使用,直接加载url地址
WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://developer.apple.com/reference/webkit"]]];
[self.view addSubview:webView];
自定义配置
再WKWebView里面注册供JS调用的方法,是通过WKUserContentController类下面的方法:
// 创建配置
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
// 创建UserContentController(提供Javascript向webView发送消息的方法)
WKUserContentController* userContent = [[WKUserContentController alloc] init];
// 添加消息处理,注意:self指代的对象需要遵守WKScriptMessageHandler协议,结束时需要移除
[userContent addScriptMessageHandler:self name:@"NativeMethod"];
// 将UserConttentController设置到配置文件
config.userContentController = userContent;
// 高端的自定义配置创建WKWebView
WKWebView *webView = [[WKWebView alloc] initWithFrame:[UIScreen mainScreen].bounds configuration:config];
// 设置访问的URL
NSURL *url = [NSURL URLWithString:@"https://developer.apple.com/reference/webkit"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
[self.view addSubview:webView];
实现WKScriptMessageHandler协议方法
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
// 判断是否是调用原生的
if ([@"NativeMethod" isEqualToString:message.name]) {
// 判断message的内容,然后做相应的操作
if ([@"close" isEqualToString:message.body]) {
}
}
}
typedef NS_ENUM(NSInteger, WKNavigationActionPolicy) {
WKNavigationActionPolicyCancel, // 取消跳转
WKNavigationActionPolicyAllow, // 允许跳转
} API_AVAILABLE(macosx(10.10), ios(8.0));
// 1 在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSLog(@"1-------在发送请求之前,决定是否跳转 -->%@",navigationAction.request);
decisionHandler(WKNavigationActionPolicyAllow);
}
// 2 页面开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
NSLog(@"2-------页面开始加载时调用");
}
// 3 在收到响应后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
/// 在收到服务器的响应头,根据response相关信息,决定是否跳转。decisionHandler必须调用,来决定是否跳转,参数WKNavigationActionPolicyCancel取消跳转,WKNavigationActionPolicyAllow允许跳转
NSLog(@"3-------在收到响应后,决定是否跳转");
decisionHandler(WKNavigationResponsePolicyAllow);
}
// 4 当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
NSLog(@"4-------当内容开始返回时调用");
}
// 5 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
NSLog(@"5-------页面加载完成之后调用");
}
// 6 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation {
NSLog(@"6-------页面加载失败时调用");
}
// 接收到服务器跳转请求之后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation {
NSLog(@"-------接收到服务器跳转请求之后调用");
}
// 数据加载发生错误时调用
- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
NSLog(@"----数据加载发生错误时调用");
}
// 需要响应身份验证时调用 同样在block中需要传入用户身份凭证
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
//用户身份信息
NSLog(@"----需要响应身份验证时调用 同样在block中需要传入用户身份凭证");
NSURLCredential *newCred = [NSURLCredential credentialWithUser:@""
password:@""
persistence:NSURLCredentialPersistenceNone];
// 为 challenge 的发送方提供 credential
[[challenge sender] useCredential:newCred forAuthenticationChallenge:challenge];
completionHandler(NSURLSessionAuthChallengeUseCredential,newCred);
}
// 进程被终止时调用
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
NSLog(@"----------进程被终止时调用");
}
OC-WKWebView(本地数据) 源码
本地数据加载方式一:
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Javascript" ofType:@"html"]]]];
本地数据加载方式二:
NSString *text = @"
NSString *baseURL = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Html"];
[self.webView loadHTMLString:text baseURL:[NSURL fileURLWithPath:baseURL]];
有些Html带有斜杠的,注意使用分隔符
NSString *name = @"
OC-WKWebView(网络连接) 源码
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];
Swift-WKWebView(本地数据) 源码
webView.load(URLRequest(url: URL(fileURLWithPath: Bundle.main.path(forResource: "Javascript", ofType: "html") ?? "")))
Swift-WKWebView(网络连接) 源码
guard let url = URL(string: "https://www.baidu.com") else { return }
let request = URLRequest(url: url)
webView.load(request)
OC 技术 WKWebView新闻详情(源码)
OC 技术 UIWebView新闻详情
OC 技术 WKWebView OC跟JS JS跟OC交互(视频+源码)
OC 技术 商品详情WebView加载详情图片(代码+视频讲解)