开发App的过程中,常常会遇到在App内部加载网页,通常用
UIWebView
加载。这个自iOS2开始使用的网页加载器一直是开发的心病
:加载速度慢,占用内存多,优化困难。如果加载网页多,还可能因为过量占用内存而给系统kill
掉。各种优化的方法效果也不那么明显(点击查看常用优化方法)。
iOS8以后,苹果推出了新框架Wekkit
,提供了替换UIWebView
的组件WKWebView
。各种UIWebView
的问题没有了,速度更快了,占用内存少了,一句话,WKWebView
是App内部加载网页的最佳选择!
先看下 WKWebView
的特性:
- 在性能、稳定性、功能方面有很大提升(最直观的体现就是加载网页是占用的内存,模拟器加载百度与开源中国网站时,WKWebView占用23M,而UIWebView占用85M);
- 允许JavaScript的Nitro库加载并使用(UIWebView中限制);
- 支持了更多的HTML5特性;
- 高达60fps的滚动刷新率以及内置手势;
- 将UIWebViewDelegate与UIWebView重构成了14类与3个协议(查看苹果官方文档);
然后从以下几个方面说下WKWebView
的基本用法:
- 加载网页
- 加载的状态回调
- 新的
WKUIDelegate
协议 - 动态加载并运行
JS
代码 - webView 执行
JS
代码 -
JS
调用App注册过的方法
一、加载网页
加载网页或HTML代码的方式与UIWebView
相同,代码示例如下:
WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];
[self.view addSubview:webView];
二、加载的状态回调 (WKNavigationDelegate)
用来追踪加载过程(页面开始加载、加载完成、加载失败)的方法:
// 页面开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavig ation:(WKNavigation *)navigation;
// 当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation;
// 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation;
// 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNaviga tion:(WKNavigation *)navigation;
页面跳转的代理方法:
// 接收到服务器跳转请求之后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirect ForProvisionalNavigation :(WKNavigation *)navigation;
// 在收到响应后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigatio nResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePoli cy))decisionHandler;
// 在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigatio nAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy ))decisionHandler;
三、新的WKUIDelegate
协议
这个协议主要用于WKWebView
处理web界面的三种提示框(警告框、确认框、输入框),下面是警告框的例子:
- (void)webView:(WKWebView *)webView runmessage initiatedByFrame:(void (^)())completionHandler;