WKWebView简介
WKWebView是WebKit框架下的,它继承自UIView,因此使用WKWebview的时候需要引入WebKit框架。
WKWebView算是iOS 8推出的UIWebView的升级版,UIWebView笨重难用,还有内存泄漏。2014年,WKWebView自诩拥有和Safari相同的JavaScript引擎,高效的app和web信息交换通道,成为WWDC 2014上的最亮点。
WKWebView的特点
性能高,稳定性好,占用的内存比较小;
支持JS交互
支持HTML 5 新特性
可以添加进度条
支持内建手势
据说高达60fps的刷新频率(不卡)
将UIWebViewDelegate与UIWebView重构成了14个类与3个协议(查看苹果官方文档)
WKWebView的属性
//初始化时,自定义的配置(只读)
@property (nonatomic, readonly, copy) WKWebViewConfiguration *configuration;
//代理
@property (nullable, nonatomic, weak) id <WKNavigationDelegate> navigationDelegate;
@property (nullable, nonatomic, weak) id <WKUIDelegate> UIDelegate;
//访问历史的一个列表,历史记录
@property (nonatomic, readonly, strong) WKBackForwardList *backForwardList
//当前网页的标题(只读)
@property (nullable, nonatomic, readonly, copy) NSString *title;
//当前网页URL
@property (nullable, nonatomic, readonly, copy) NSURL *URL;
//是否正在加载
@property (nonatomic, readonly, getter=isLoading) BOOL loading;
//进度(有了这个以后就不用自己写假的进度条了)
@property (nonatomic, readonly) double estimatedProgress;
//是否安全加密加载页面(只读)
@property (nonatomic, readonly) BOOL hasOnlySecureContent;
@property (nonatomic, readonly, nullable) SecTrustRef serverTrust API_AVAILABLE(macosx(10.12), ios(10.0));
//获取能否返回上一级
@property (nonatomic, readonly) BOOL canGoBack;
//获取能否跳转下一级
@property (nonatomic, readonly) BOOL canGoForward;
//是否允许水平滑动前进后退页面(默认NO)
@property (nonatomic) BOOL allowsBackForwardNavigationGestures;
//用户设置的代理信息,没有为nil(9.0)
@property (nullable, nonatomic, copy) NSString *customUserAgent API_AVAILABLE(macosx(10.11), ios(9.0));
//是否支持链接预览,支持3D Touch查看等
@property (nonatomic) BOOL allowsLinkPreview API_AVAILABLE(macosx(10.11), ios(9.0));
//内置的scrollView
@property (nonatomic, readonly, strong) UIScrollView *scrollView;
//是否支持放大手势,default NO
@property (nonatomic) BOOL allowsMagnification;
//放大因子,default 1
@property (nonatomic) CGFloat magnification;
WKWebView的方法
- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
//设置加载URL请求
- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;
//加载导航到所请求的文件系统上的文件URL
- (nullable WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL API_AVAILABLE(macosx(10.11), ios(9.0));
//如果网页是国际通用的UTF-8编码的,也可以用这个方法加载数据。
- (nullable WKNavigation *)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;
//以二进制的方式加载数据
- (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; //刷新WebView页面
- (nullable WKNavigation *)reloadFromOrigin; //重新载入当前页面,进行端到端的验证使用缓存验证条件
- (void)stopLoading; //停止加载WebView页面
//执行JS语言
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;
//根据设置的缩放因子来缩放页面,并居中显示结果在指定的点
- (void)setMagnification:(CGFloat)magnification centeredAtPoint:(CGPoint)point;
WKWebView的代理方法
1、WKNavigationsDelegate
追踪加载过程的代理方法
//页面开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation;
//当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation;
// 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation;
//页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error;
页面跳转的代理方法
//接收到服务器跳转请求之后再执行
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation;
//在收到响应后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
//在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
2、WKUIDelegate
//创建一个新的WebVeiw
- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures;
//WebVeiw关闭(9.0中的新方法)
- (void)webViewDidClose:(WKWebView *)webView NS_AVAILABLE(10_11, 9_0);
/* 弹出一个警告框(与JS交互)
@param webView 实现该代理的WebView
@param message 警告框中的内容
@param frame 主窗口
@param completionHandler 警告框消失调用
*/
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler;
//弹出一个输入框(与JS交互的)
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler;
//显示一个确认框(JS的)
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler;
3、WKScriptMessageHandler
以上协议的方法都是可选的,本协议的一个方法是必须实现的,这个方法是提高App与web端交互的关键,它可以直接将接收到的JS脚本转化成OC或者Swift对象
//从web端接收到一个JS脚本时调用
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;
⚠️在Swift中,遵循WKScriptMessageHandler协议的必须实现协议方法,否则会报错:Type ‘WKWebViewController’ does not conform to protocol ‘WKScriptMessageHandler’