参考文章:http://www.cocoachina.com/ios/20180831/24753.html

WK时苹果在iOS8.0之后推出的控件,相比于UIWebView:

  • 内存消耗少;
  • 解决了网页加载时的内存泄漏问题;
  • 与HTML页面的交互更方便;
  • 总之,其性能比UIWebView好很多。

使用时,首先要添加头文件:

#import <WebKit/WebKit.h>

简单创建一个WKWebView:

    self.iWKWebView = [[WKWebView alloc]initWithFrame:CGRectMake(, , [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height-)];
//此处协议下面会讲到
self.iWKWebView.navigationDelegate = self;
self.iWKWebView.UIDelegate = self;
self.iWKWebView.allowsBackForwardNavigationGestures = YES;
NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.iWKWebView loadRequest:request];
[self.view addSubview:self.iWKWebView];

基本用法和UIWebView差不多。

这里介绍几个主要的类:

  • WKWebView
  • WKWebViewConfiguration

  • WKPreferences

  • WKUserContentController

  • WKWebsiteDataStore


1. WKWebView:

常用属性:

// 导航代理
@property (nullable, nonatomic, weak) id <WKNavigationDelegate> navigationDelegate;
// UI代理
@property (nullable, nonatomic, weak) id <WKUIDelegate> UIDelegate;
// 页面标题, 一般使用KVO动态获取
@property (nullable, nonatomic, readonly, copy) NSString *title;
// 页面加载进度, 一般使用KVO动态获取
@property (nonatomic, readonly) double estimatedProgress;
// 可返回的页面列表, 已打开过的网页, 有点类似于navigationController的viewControllers属性
@property (nonatomic, readonly, strong) WKBackForwardList *backForwardList;
// 页面url
@property (nullable, nonatomic, readonly, copy) NSURL *URL;
// 页面是否在加载中
@property (nonatomic, readonly, getter=isLoading) BOOL loading;
// 是否可返回
@property (nonatomic, readonly) BOOL canGoBack;
// 是否可向前
@property (nonatomic, readonly) BOOL canGoForward;
// WKWebView继承自UIView, 所以如果想设置scrollView的一些属性, 需要对此属性进行配置
@property (nonatomic, readonly, strong) UIScrollView *scrollView;
// 是否允许手势左滑返回上一级, 类似导航控制的左滑返回
@property (nonatomic) BOOL allowsBackForwardNavigationGestures;
//自定义UserAgent, 会覆盖默认的值 ,iOS 9之后有效
@property (nullable, nonatomic, copy) NSString *customUserAgent

常用方法:

// 带配置信息的初始化方法
// configuration 配置信息
- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
// 加载请求
- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;
// 加载HTML
- (nullable WKNavigation *)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;
// 返回上一级
- (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;

2. WKWebViewConfiguration:配置信息

可以用配置信息来初始化WKWebView.

属性有:

    //关于网页的设置
@property (nonatomic, strong) WKPreferences *preferences;
//JavaScript与原生交互的桥梁
@property (nonatomic, strong) WKUserContentController *userContentController;
//提供了网站所能使用的数据类型
@property (nonatomic, strong) WKWebsiteDataStore *websiteDataStore API_AVAILABLE(macosx(10.11), ios(9.0));
//是否允许播放媒体文件
@property (nonatomic) BOOL allowsAirPlayForMediaPlayback API_AVAILABLE(macosx(10.11), ios(9.0));
//是使用h5的视频播放器在线播放, 还是使用原生播放器全屏播放
@property (nonatomic) BOOL allowsInlineMediaPlayback;
//需要用户允许才能播放的媒体类型
@property (nonatomic) WKAudiovisualMediaTypes mediaTypesRequiringUserActionForPlayback API_AVAILABLE(macosx(10.12), ios(10.0));

2.1  WKPreference:

   WKPreferences *preference = [[WKPreferences alloc]init];
//最小字体大小
preference.minimumFontSize = ;
//是否支持javaScript,默认YES
preference.javaScriptEnabled = YES;
//是否允许不经过用户交互由javaScript自动打开窗口
preference.javaScriptCanOpenWindowsAutomatically = YES;

2.2  WKUserContentController

// 注入JavaScript与原生交互协议
// JS 端可通过 window.webkit.messageHandlers..postMessage() 发送消息
- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;
// 移除注入的协议, 在deinit方法中调用
- (void)removeScriptMessageHandlerForName:(NSString *)name;
// 通过WKUserScript注入需要执行的JavaScript代码
- (void)addUserScript:(WKUserScript *)userScript;
// 移除所有注入的JavaScript代码
- (void)removeAllUserScripts;

使用WKUserContentController注入的交互协议, 需要遵循WKScriptMessageHandler协议, 在其协议方法中获取JavaScript端传递的事件和参数:

JS调用OC:

简单理解就是:[userController addScriptMessageHandler:self name:@"JSSendToOC"];//userController是一个WKUserContentController对象,‘JSSendToOC’是方法名,

当JS端通过window.webkit.messageHandlers.JSSendToOC.postMessage()方法调用'JSSendToOC'方法时,我们可以通过下面的协议方法获取到JS端传过来的数据,做我们的操作。

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;
WKScriptMessage包含了传递的协议名称及参数, 主要从下面的属性中获取:
// 协议名称, 即上面的add方法传递的name
@property (nonatomic, readonly, copy) NSString *name;
// 传递的参数
@property (nonatomic, readonly, copy) id body;

 OC调用JS:

   NSString *js = @"callJsFunction('hahaha')";
[self.webView evaluateJavaScript:js completionHandler:^(id _Nullable response, NSError * _Nullable error) {
NSLog(@"response:%@..error:%@",response,error);
}];

这里是调用了JS的‘callJsFunction’方法,这个方法名是随便起的。

2.3  WKWebsiteDataStore

WKWebsiteDataStore 提供了网站所能使用的数据类型,包括 cookies,硬盘缓存,内存缓存活在一些WebSQL的数据持久化和本地持久化。可通过 WKWebViewConfiguration类的属性 websiteDataStore 进行相关的设置。WKWebsiteDataStore相关的API也比较简单:

// 默认的data store
+ (WKWebsiteDataStore *)defaultDataStore;
// 如果为webView设置了这个data Store,则不会有数据缓存被写入文件
// 当需要实现隐私浏览的时候,可使用这个
+ (WKWebsiteDataStore *)nonPersistentDataStore;
// 是否是可缓存数据的,只读
@property (nonatomic, readonly, getter=isPersistent) BOOL persistent;
// 获取所有可使用的数据类型
+ (NSSet<NSString *> *)allWebsiteDataTypes;
// 查找指定类型的缓存数据
// 回调的值是WKWebsiteDataRecord的集合
- (void)fetchDataRecordsOfTypes:(NSSet<NSString *> *)dataTypes completionHandler:(void (^)(NSArray<WKWebsiteDataRecord *> *))completionHandler;
// 删除指定的纪录
// 这里的参数是通过上面的方法查找到的WKWebsiteDataRecord实例获取的
- (void)removeDataOfTypes:(NSSet<NSString *> *)dataTypes forDataRecords:(NSArray<WKWebsiteDataRecord *> *)dataRecords completionHandler:(void (^)(void))completionHandler;
// 删除某时间后修改的某类型的数据
- (void)removeDataOfTypes:(NSSet<NSString *> *)websiteDataTypes modifiedSince:(NSDate *)date completionHandler:(void (^)(void))completionHandler;
// 保存的HTTP cookies
@property (nonatomic, readonly) WKHTTPCookieStore *httpCookieStore

dataTypes:

// 硬盘缓存
WKWebsiteDataTypeDiskCache,
// HTML离线web应用程序缓存
WKWebsiteDataTypeOfflineWebApplicationCache,
// 内存缓存
WKWebsiteDataTypeMemoryCache,
// 本地缓存
WKWebsiteDataTypeLocalStorage,
// cookies
WKWebsiteDataTypeCookies,
// HTML会话存储
WKWebsiteDataTypeSessionStorage,
// IndexedDB 数据库
WKWebsiteDataTypeIndexedDBDatabases,
// WebSQL 数据库
WKWebsiteDataTypeWebSQLDatabases

dataRecord:

// 展示名称, 通常是域名
@property (nonatomic, readonly, copy) NSString *displayName;
// 包含的数据类型
@property (nonatomic, readonly, copy) NSSet<NSString *> *dataTypes;

关于此类的简单使用:

1.删除指定时间的所有类型数据

    NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];
NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:];
[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{
// Done
NSLog(@"释放");
}];

2.查找删除

    WKWebsiteDataStore *dataStore = [WKWebsiteDataStore defaultDataStore];
[dataStore fetchDataRecordsOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] completionHandler:^(NSArray<WKWebsiteDataRecord *> * _Nonnull records) {
for (WKWebsiteDataRecord *record in records) {
[dataStore removeDataOfTypes:record.dataTypes forDataRecords:@[record] completionHandler:^{
// done
}];
}
}];

3.查找删除特定的内容

   WKWebsiteDataStore *dataStore = [WKWebsiteDataStore defaultDataStore];
[dataStore fetchDataRecordsOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] completionHandler:^(NSArray<WKWebsiteDataRecord *> * _Nonnull records) {
for (WKWebsiteDataRecord *record in records) {
if ([record.displayName isEqualToString:@"baidu"]) {
[dataStore removeDataOfTypes:record.dataTypes forDataRecords:@[record] completionHandler:^{
// done
}];
}
}
}];

WKNavigationDelegate:

#pragma mark - WKNavigationDelegate

//请求加载之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
NSLog(@"加载前允许跳转");
decisionHandler(WKNavigationActionPolicyAllow);
}
//开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation{
NSLog(@"开始加载");
}
//收到响应开始加载后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
NSLog(@"收到响应后允许跳转");
decisionHandler(WKNavigationResponsePolicyAllow);
}
//内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation{
NSLog(@"开始返回内容");
}
//加载完成时调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation{
NSLog(@"加载完成");
self.title = webView.title;
}
//加载失败调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error{
NSLog(@"加载失败");
} //收到服务器重定向请求后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation{
NSLog(@"服务器重定向");
}
//当main frame最后下载数据失败时,会回调
- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error{
NSLog(@"返回内容发生错误");
} //用于授权验证的API,与AFN、UIWebView的授权验证API是一样的
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling,nil);
} //当web content处理完成时,会回调
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView API_AVAILABLE(macosx(10.11), ios(9.0)){
NSLog(@"WebContent完成");
}

这里放一个完整的WKWebView例子,仅供参考:

//初始化WKPreferences,并设置相关属性
WKPreferences *preference = [[WKPreferences alloc]init]; //初始化WKUserContentController,并设置相关属性
WKUserContentController *userController = [[WKUserContentController alloc]init];
// 添加在js中操作的对象名称,通过该对象来向web view发送消息
// JS 端可通过 window.webkit.messageHandlers..postMessage() 发送消息
// <script type="text/javascript">
// function clickBtn(){
// var dict = {"name":"tom","age":"20"};
// window.webkit.messageHandlers.JSSendToOC.postMessage(dict);
// }
// </script>
[userController addScriptMessageHandler:self name:@"JSSendToOC"]; //初始化WKWebsiteDataStore,并设置相关属性
WKWebsiteDataStore *dataStore = [WKWebsiteDataStore defaultDataStore];
// 如果为webView设置了这个data Store,则不会有数据缓存被写入文件
// 当需要实现隐私浏览的时候,可使用这个
// WKWebsiteDataStore *dataStore = [WKWebsiteDataStore nonPersistentDataStore]; //配置信息
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc]init];
configuration.preferences = preference;
configuration.userContentController = userController;
configuration.websiteDataStore = dataStore; self.iWKWebView = [[WKWebView alloc]initWithFrame:CGRectMake(, , [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height-) configuration:configuration]; self.iWKWebView.navigationDelegate = self;
self.iWKWebView.UIDelegate = self; self.iWKWebView.allowsBackForwardNavigationGestures = YES;
NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[self.iWKWebView loadRequest:request];
[self.view addSubview:self.iWKWebView];

再加一个知识点:WKWebView加载的时候添加一个自定义的进度条。

此时我们需要获取到webview加载的进度数值。

这里可以通过添加监听来获取。

[self.iWKWebView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
estimatedProgress是WKWebView的一个属性。
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{

    if ([keyPath isEqualToString:@"estimatedProgress"] && object==self.iWKWebView) {
//获取到webview的进度数值,加载自定义的进度条
//self.iWKWebView.estimatedProgress
} }

iOS-WKWebView的使用的更多相关文章

  1. iOS WKWebview 网页开发适配指南

    iOS WKWebview 网页开发适配指南 微信iOS客户端将于2017年3月1日前逐步升级为WKWebview内核,需要网页开发者提前做好网站的兼容检查和适配.如有问题,可参考文末联系方式,向我们 ...

  2. iOS WKWebView详解

    UIWebView就不用说了,这个过时了,现在iOS8以后建议都使用WKWebView. WKWebView 是现代 WebKit API 在 iOS 8 和 OS X Yosemite 应用中的核心 ...

  3. 微信iOS WKWebview 网页开发适配指南

    微信iOS客户端将于2017年3月1日前逐步升级为WKWebview内核,需要网页开发者提前做好网站的兼容检查和适配. 背景 WKWebView 是苹果在iOS 8中引入的新组件,目的是提供一个现代的 ...

  4. ios WKWebView 与 JS 交互实战技巧

    一.WKWebView 由于Xcode8发布之后,编译器开始不支持iOS 7了,这样我们的app也改为最低支持iOS 8.0,既然需要与web交互,那自然也就选择使用了 iOS 8.0之后 才推出的新 ...

  5. iOS WKWebview 网页开发适配指南【转】

    微信iOS客户端将于2017年3月1日前逐步升级为WKWebview内核,需要网页开发者提前做好网站的兼容检查和适配.如有问题,可参考文末联系方式,向我们咨询. 背景 WKWebView 是苹果在iO ...

  6. iOS wkwebview https 加载不受信用的站点

    iOS 9.0以上直接设置WKNavigationDelegate代理 func webView(_ webView: WKWebView, didReceive challenge: URLAuth ...

  7. iOS WKWebView OC 与 JS 交互学习

    我写WKWebView 想让 服务端相应 一个 方法但是不响应,根据 UIWebView 用 JSContext就能拿到响应的处理经验是不是服务端 也需要 对 WKwebView有兼容的一个写法??? ...

  8. iOS WKWebView

    Webkit 是 iOS 8.0 后提供的新的框架,组件WKWebView比较UIWebView 速度更快.占用内存更少了,可支持性更多 WKWebView可通过KVO监听属性 title.estim ...

  9. iOS WKWebView的javascript alert 不弹的解决方案

    - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiate ...

  10. iOS wkwebview懒加载中遇到的问题

    这是我遇到的问题,也许是个例,就算狗血了点吧 需求: 当前界面(mainVC)响应点击事件,传值给webviewController(webVC)其中包含网址,此时如果在webVC中对wkwebvie ...

随机推荐

  1. fiddler 使用方法汇总

    作为网络开发人员,怎能不使用一些抓包工具呢?fiddler是个不错的选择. 不过,一般情况下,我们往往使用浏览器自带的控制台的[网络]选项就可以达到查看数据的通信情况了,当然,一些浏览器不容易捕捉的事 ...

  2. 带你入门Python爬虫,8个常用爬虫技巧盘点

    python作为一门高级编程语言,它的定位是优雅.明确和简单. 我学用python差不多一年时间了, 用得最多的还是各类爬虫脚本, 写过抓代理本机验证的脚本.写过论坛中自动登录自动发贴的脚本 写过自动 ...

  3. jmeter获取cookies信息(配置)

    jmeter发送请求后,响应信息里获取不到cookies(实际上会返回一个cookies),解决方法: 在jmeter.properties里找到CookieManager.save.cookies, ...

  4. Linux快速目录间切换cd pushd popd

    1.   cd -     当前目录和之前所在的目录之间的切换 2.   cd + Alt . 用上次命令的最后一个目录路径 要用上上次命令的最后一个目录,就Alt+.两次就可以了 3.   push ...

  5. python修改文件中字符串并写入

    python实际工作中,做一些小工具,很方便.最近在做一个格式转换工具时候,用到了替换文件中特定字符串的 功能.当初没直接想出来,就在网上查了一下,做个记录,方便后续使用. # -*- coding: ...

  6. linux中环境变量PATH设置错误,导致ls cd 等命令不能使用,提示:没有那个文件或目录

    在CentOS7中执行了 PATH=/opt/:$PATH 然后执行ls时,出现 ls-bash: ls: 没有那个文件或目录 试了试其他命令也一样无法使用 后来执行 : export PATH=/u ...

  7. django-pure-pagination实现分页

    django-pure-paginations是一个第三方的分页插件 安装 django-pure-pagination pip install django-pure-pagination 在set ...

  8. Git使用教程:最详细、最傻瓜、最浅显、真正手把手教!

    Git使用教程:最详细.最傻瓜.最浅显.真正手把手教! 蘇小小 Web项目聚集地 9月16日 作者 | 蘇小小 编辑 | 王久一 来源 | 慕课网 导读:因为教程详细,所以行文有些长,新手边看边操作效 ...

  9. Xpath定位方法深入探讨及元素定位失败常见情况

    一.Xpath定位方法深入探讨 (1)常用的Xpath定位方法及其特点 使用绝对路径定位元素. 例如: driver.findElement(By.xpath("/html/body/div ...

  10. Postgresql操作json格式数据

    1.select array_to_json('{{1,5},{99,100}}'::int[])