iOS8之后,WKWebView相对于UIWebView的高性能,替换已成趋势。相比之下,WKWebView的优势之处在于:
- 性能强,更稳定。
- 支持更多的html5特性。
- 占用内存远低于UIWebView。
- 具有和Safari相同的JS引擎能力。
- ...
1.使用
#import <WebKit/WebKit.h>
初始化方法:
- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration;
- (instancetype)initWithFrame:(CGRect)frame;
加载网页
NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
加载本地html页面
NSString * htmlPath = [[NSBundle mainBundle] pathForResource:@"demo1" ofType:@"html"];
[self.webView loadFileURL:[NSURL fileURLWithPath:htmlPath] allowingReadAccessToURL:[NSURL fileURLWithPath:htmlPath]];
加载html字符串
- (nullable WKNavigation *)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;
支持返回手势,像iOS自带的手势返回一样。
self.webView.allowsBackForwardNavigationGestures = YES;
2.协议
-
WKNavigationDelegate
:关于加载页面的代理方法
self.webView.navigationDelegate = self;
//开始加载时调用
-(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
}
//当内容开始返回时调用
-(void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
}
//页面加载完成之后调用
-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
}
// 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation
{
}
//https接口时用到
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential,card);
}
}
//打电话url
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURL *URL = navigationAction.request.URL;
NSString *scheme = [URL scheme];
if ([scheme isEqualToString:@"tel"]) {
NSString *resourceSpecifier = [URL resourceSpecifier];
NSString *callPhone = [NSString stringWithFormat:@"telprompt://%@", resourceSpecifier];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:callPhone]];
}
decisionHandler(WKNavigationActionPolicyAllow);
}
-
WKUIDelegate
:提供用原生控件显示网页的方法回调
self.webView.UIDelegate = self;
//调用弹出框函数
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
{
//此处调用OC弹出框
}
//调用确认框函数
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler
{
//此处调用OC弹出框
}
//调用输入框函数
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(nonnull NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(nonnull WKFrameInfo *)frame completionHandler:(nonnull void (^)(NSString * _Nullable))completionHandler
{
//此处调用OC弹出框
}
-
WKScriptMessageHandler
:提供从网页中收消息的回调方法,后面提到。处理JS传递数据到OC中来。
3.类
-
WKWebViewConfiguration
:初始化webview的设置
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc]init];
// 设置偏好设置
config.preferences = [[WKPreferences alloc] init];
// 默认为10
config.preferences.minimumFontSize = 10;
// 默认认为YES
config.preferences.javaScriptEnabled = YES;
// 在iOS上默认为NO,表示不能自动通过窗口打开
config.preferences.javaScriptCanOpenWindowsAutomatically = NO;
config.userContentController = [[WKUserContentController alloc] init];
//注册两个对象,后面与JS交互时使用。需遵守WKScriptMessageHandler协议
[config.userContentController addScriptMessageHandler:self name:@"UserInfo"];
[config.userContentController addScriptMessageHandler:self name:@"Test2"];
-
WKBackForwardList
:之前访问过得前进和后退的web页面,有backList
和forwardList
等属性。
4.监听进度条
通过监听estimatedProgress可以获取它的加载进度 ,需使用到WKNavigationDelegate的代理方法,还可以监听title,loading等属性
[self.webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSString *,id> *)change
context:(void *)context
{
if ([keyPath isEqualToString:@"estimatedProgress"])
{
NSLog(@"progress: %f", self.webView.estimatedProgress);
self.progressView.progress = self.webView.estimatedProgress;
}
// 加载完成
if (!self.webView.loading)
{
[UIView animateWithDuration:0.5 animations:^{
self.progressView.alpha = 0.0;
}];
}
}
- (void)dealloc {
[self.webView removeObserver:self forKeyPath:@"estimatedProgress"];
}
5.WKScriptMessageHandler处理JS传过来的数据。
上面提到过的,注册两个对象
[config.userContentController addScriptMessageHandler:self name:@"UserInfo"];
[config.userContentController addScriptMessageHandler:self name:@"Test2"];
JS中代码
$("#test1btn").click(function(){
var em = $("#inputEmail").val();
var pas = $("#inputPassword").val();
var dat = {"email":em,"password":pas};
window.webkit.messageHandlers.UserInfo.postMessage({body: dat});
});
$("#test2btn").click(function(){
var dat = JSON.stringify({"title":"我的测试","name":"zhiyuehl","sex":0});
window.webkit.messageHandlers.Test2.postMessage({body: dat});
});
//OC调用JS方法
function onOCChangeMethod(email,passwd) {
$("#inputEmail").val(email);
$("#inputPassword").val(passwd);
}
OC的代理方法:WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
{
//JS传过来的数据
if ([message.name isEqualToString:@"UserInfo"]) {
NSLog(@"test1传值-------------%@",message.body);
}
//JS调用OC方法
if ([message.name isEqualToString:@"Test2"]) {
[self callCamera:message];
}
}
OC调用JS方法:
- (void)callCamera:(WKScriptMessage *)message
{
NSLog(@"test2JS传值----%@",message.body);
[self ocInvokeJSMethod];
}
//OC调用JS方法
- (void)ocInvokeJSMethod
{
NSString *js = [NSString stringWithFormat:@"onOCChangeMethod('775445353@qq.com','123123')"];
[_webView evaluateJavaScript:js completionHandler:^(id _Nullable obj, NSError * _Nullable error) {
NSLog(@"---%@",error.localizedDescription);
}];
}
最后
OC与JS交互demo:github地址
网友评论