经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
iOS-WKWebView的使用
来源:cnblogs  作者:昔年随心  时间:2018/10/18 8:55:16  对本文有异议

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

 

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

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

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

#import <WebKit/WebKit.h>

简单创建一个WKWebView:

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

基本用法和UIWebView差不多。

这里介绍几个主要的类:

  • WKWebView
  • WKWebViewConfiguration

  • WKPreferences

  • WKUserContentController

  • WKWebsiteDataStore


 

 

1. WKWebView:

常用属性:

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

常用方法:

  1. // 带配置信息的初始化方法
  2. // configuration 配置信息
  3. - (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
  4. // 加载请求
  5. - (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;
  6. // 加载HTML
  7. - (nullable WKNavigation *)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;
  8. // 返回上一级
  9. - (nullable WKNavigation *)goBack;
  10. // 前进下一级, 需要曾经打开过, 才能前进
  11. - (nullable WKNavigation *)goForward;
  12. // 刷新页面
  13. - (nullable WKNavigation *)reload;
  14. // 根据缓存有效期来刷新页面
  15. - (nullable WKNavigation *)reloadFromOrigin;
  16. // 停止加载页面
  17. - (void)stopLoading;
  18. // 执行JavaScript代码
  19. - (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;

 

2. WKWebViewConfiguration:配置信息

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

属性有:

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

 

2.1  WKPreference:

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

 

2.2  WKUserContentController

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

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

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

 

2.3  WKWebsiteDataStore

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

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

dataTypes:

  1. // 硬盘缓存
  2. WKWebsiteDataTypeDiskCache,
  3. // HTML离线web应用程序缓存
  4. WKWebsiteDataTypeOfflineWebApplicationCache,
  5. // 内存缓存
  6. WKWebsiteDataTypeMemoryCache,
  7. // 本地缓存
  8. WKWebsiteDataTypeLocalStorage,
  9. // cookies
  10. WKWebsiteDataTypeCookies,
  11. // HTML会话存储
  12. WKWebsiteDataTypeSessionStorage,
  13. // IndexedDB 数据库
  14. WKWebsiteDataTypeIndexedDBDatabases,
  15. // WebSQL 数据库
  16. WKWebsiteDataTypeWebSQLDatabases

dataRecord:

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

关于此类的简单使用:

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

  1. NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];
  2. NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
  3. [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{
  4. // Done
  5. NSLog(@"释放");
  6. }];

 

2.查找删除

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

 

3.查找删除特定的内容

  1. WKWebsiteDataStore *dataStore = [WKWebsiteDataStore defaultDataStore];
  2. [dataStore fetchDataRecordsOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] completionHandler:^(NSArray<WKWebsiteDataRecord *> * _Nonnull records) {
  3. for (WKWebsiteDataRecord *record in records) {
  4. if ([record.displayName isEqualToString:@"baidu"]) {
  5. [dataStore removeDataOfTypes:record.dataTypes forDataRecords:@[record] completionHandler:^{
  6. // done
  7. }];
  8. }
  9. }
  10. }];

 

WKNavigationDelegate:

  1. #pragma mark - WKNavigationDelegate
  2.  
  3. //请求加载之前,决定是否跳转
  4. - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
  5. NSLog(@"加载前允许跳转");
  6. decisionHandler(WKNavigationActionPolicyAllow);
  7. }
  8. //开始加载时调用
  9. - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation{
  10. NSLog(@"开始加载");
  11. }
  12. //收到响应开始加载后,决定是否跳转
  13. - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
  14. NSLog(@"收到响应后允许跳转");
  15. decisionHandler(WKNavigationResponsePolicyAllow);
  16. }
  17. //内容开始返回时调用
  18. - (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation{
  19. NSLog(@"开始返回内容");
  20. }
  21. //加载完成时调用
  22. - (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation{
  23. NSLog(@"加载完成");
  24. self.title = webView.title;
  25. }
  26. //加载失败调用
  27. - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error{
  28. NSLog(@"加载失败");
  29. }
  30. //收到服务器重定向请求后调用
  31. - (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation{
  32. NSLog(@"服务器重定向");
  33. }
  34. //当main frame最后下载数据失败时,会回调
  35. - (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error{
  36. NSLog(@"返回内容发生错误");
  37. }
  38. //用于授权验证的API,与AFN、UIWebView的授权验证API是一样的
  39. - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
  40. completionHandler(NSURLSessionAuthChallengePerformDefaultHandling,nil);
  41. }
  42. //当web content处理完成时,会回调
  43. - (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView API_AVAILABLE(macosx(10.11), ios(9.0)){
  44. NSLog(@"WebContent完成");
  45. }
View Code

 

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

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

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号