IOS进阶之WKWebView

Xcode8发布以后,编译器开始不支持IOS7,所以很多应用在适配IOS10之后都不在适配IOS7了,其中包括了很多大公司,网易新闻,滴滴出行等。因此,我们公司的应用也打算淘汰IOS7。

支持到IOS8,第一个要改的自然是用WKWebView替换原来的UIWebView。WKWebView有很多明显优势:

更多的支持HTML5的特性

官方宣称的高达60fps的滚动刷新率以及内置手势

将UIWebViewDelegate与UIWebView拆分成了14类与3个协议,以前很多不方便实现的功能得以实现。文档

Safari相同的JavaScript引擎

占用更少的内存

UIWebView


WKWebView


因此,使用WkWebview替换UIWebView还是很有必要的。

基本使用方法

WKWebView有两个delegate,WKUIDelegate 和 WKNavigationDelegate。

WKNavigationDelegate主要处理一些跳转、加载处理操作,WKUIDelegate主要处理JS脚本,确认框,警告框等。因此WKNavigationDelegate更加常用。

比较常用的方法:

OC与JS交互

WKWebview提供了API实现js交互 不需要借助JavaScriptCore或者webJavaScriptBridge。使用WKUserContentController实现js native交互。简单的说就是先注册约定好的方法,然后再调用。

JS调用OC方法

@interface ViewController (){

WKWebView * webView;

WKUserContentController* userContentController;

}

@end

@implementation ViewController

#pragma mark - lifeCircle

- (void)viewDidLoad {

[super viewDidLoad];

//配置环境

WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc]init];

userContentController =[[WKUserContentController alloc]init];

configuration.userContentController = userContentController;

webView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, 100, 100) configuration:configuration];

//注册方法

WKDelegateController * delegateController = [[WKDelegateController alloc]init];

delegateController.delegate = self;

[userContentController addScriptMessageHandler:delegateController  name:@"sayhello"];

[self.view addSubview:webView];

[webView mas_makeConstraints:^(MASConstraintMaker *make) {

make.left.equalTo(self.view);

make.right.equalTo(self.view);

make.top.equalTo(self.view);

make.bottom.equalTo(self.view);

}];

webView.UIDelegate = self;

webView.navigationDelegate = self;

[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.test.com"]]];

}

- (void)dealloc{

//这里需要注意,前面增加过的方法一定要remove掉。

[userContentController removeScriptMessageHandlerForName:@"sayhello"];

}

#pragma mark - WKScriptMessageHandler

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{

NSLog(@"name:%@\\\\n body:%@\\\\n frameInfo:%@\\\\n",message.name,message.body,message.frameInfo);

}

@end

WKDelegateController代码:

#import#import@protocol WKDelegate- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;@end@interface WKDelegateController : UIViewController@property (weak , nonatomic) iddelegate;

m代码:

#import "WKDelegateController.h"

@interface WKDelegateController ()

@end

@implementation WKDelegateController

- (void)viewDidLoad {

[super viewDidLoad];

}

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{

if ([self.delegate respondsToSelector:@selector(userContentController:didReceiveScriptMessage:)]) {

[self.delegate userContentController:userContentController didReceiveScriptMessage:message];

}}

@end

h5代码:

注意点

addScriptMessageHandler要和removeScriptMessageHandlerForName配套出现,否则会造成内存泄漏。

h5只能传一个参数,如果需要多个参数就需要用字典或者json组装。

oc调用JS方法

代码如下:

- (void)webView:(WKWebView *)tmpWebView didFinishNavigation:(WKNavigation *)navigation{

//say()是JS方法名,completionHandler是异步回调block

[webView evaluateJavaScript:@"say()" completionHandler:^(id _Nullable result, NSError * _Nullable error) {

NSLog(@"%@",result);

}];

}

h5代码同上。

WebViewJavascriptBridge

一般来说,一个好的UI总有一个大神会开发出一个好的第三方封装框架。WebViewJavascriptBridge的作者也做了一套支持WKWebView与JS交互的第三方框架:WKWebViewJavascriptBridge。

cocoaPods: pod 'WebViewJavascriptBridge', '~> 5.0.5'

github地址:https://github.com/marcuswestin/WebViewJavascriptBridge

主要方法如下:


基本的实现方法和上面写的差不多,就是封装了一下,有兴趣的童鞋可以自己pod下来使用。

推荐阅读更多精彩内容