基本使用方法


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

比较常用的方法:

  1. #pragma mark - lifeCircle
  2. - (void)viewDidLoad {
  3. [super viewDidLoad];
  4. webView = [[WKWebView alloc]init];
  5. [self.view addSubview:webView];
  6. [webView mas_makeConstraints:^(MASConstraintMaker *make) {
  7. make.left.equalTo(self.view);
  8. make.right.equalTo(self.view);
  9. make.top.equalTo(self.view);
  10. make.bottom.equalTo(self.view);
  11. }];
  12. webView.UIDelegate = self;
  13. webView.navigationDelegate = self;
  14. [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];
  15. }
  16. #pragma mark - WKNavigationDelegate
  17. // 页面开始加载时调用
  18. - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
  19. }
  20. // 当内容开始返回时调用
  21. - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
  22. }
  23. // 页面加载完成之后调用
  24. - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
  25. }
  26. // 页面加载失败时调用
  27. - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation{
  28. }
  29. // 接收到服务器跳转请求之后调用
  30. - (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{
  31. }
  32. // 在收到响应后,决定是否跳转
  33. - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
  34. NSLog(@"%@",navigationResponse.response.URL.absoluteString);
  35. //允许跳转
  36. decisionHandler(WKNavigationResponsePolicyAllow);
  37. //不允许跳转
  38. //decisionHandler(WKNavigationResponsePolicyCancel);
  39. }
  40. // 在发送请求之前,决定是否跳转
  41. - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
  42. NSLog(@"%@",navigationAction.request.URL.absoluteString);
  43. //允许跳转
  44. decisionHandler(WKNavigationActionPolicyAllow);
  45. //不允许跳转
  46. //decisionHandler(WKNavigationActionPolicyCancel);
  47. }
  48. #pragma mark - WKUIDelegate
  49. // 创建一个新的WebView
  50. - (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{
  51. return [[WKWebView alloc]init];
  52. }
  53. // 输入框
  54. - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler{
  55. completionHandler(@"http");
  56. }
  57. // 确认框
  58. - (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler{
  59. completionHandler(YES);
  60. }
  61. // 警告框
  62. - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
  63. NSLog(@"%@",message);
  64. completionHandler();
  65. }

OC与JS交互


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

JS调用OC方法

oc代码(有误,内存不释放):

  1. @interface ViewController ()<WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler>{
  2. WKWebView * webView;
  3. WKUserContentController* userContentController;
  4. }
  5. @end
  6. @implementation ViewController
  7. #pragma mark - lifeCircle
  8. - (void)viewDidLoad {
  9. [super viewDidLoad];
  10. //配置环境
  11. WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc]init];
  12. userContentController =[[WKUserContentController alloc]init];
  13. configuration.userContentController = userContentController;
  14. webView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, 100, 100) configuration:configuration];
  15. //注册方法
  16. [userContentController addScriptMessageHandler:self name:@"sayhello"];//注册一个name为sayhello的js方法
  17. [self.view addSubview:webView];
  18. [webView mas_makeConstraints:^(MASConstraintMaker *make) {
  19. make.left.equalTo(self.view);
  20. make.right.equalTo(self.view);
  21. make.top.equalTo(self.view);
  22. make.bottom.equalTo(self.view);
  23. }];
  24. webView.UIDelegate = self;
  25. webView.navigationDelegate = self;
  26. [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.test.com"]]];
  27. }
  28. - (void)dealloc{
  29. //这里需要注意,前面增加过的方法一定要remove掉。
  30. [userContentController removeScriptMessageHandlerForName:@"sayhello"];
  31. }
  32. #pragma mark - WKScriptMessageHandler
  33. - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
  34. NSLog(@"name:%@\\\\n body:%@\\\\n frameInfo:%@\\\\n",message.name,message.body,message.frameInfo);
  35. }
  36. @end

上面的OC代码如果认证测试一下就会发现dealloc并不会执行,这样肯定是不行的,会造成内存泄漏。原因是[userContentController addScriptMessageHandler:self name:@"sayhello"];这句代码造成无法释放内存。(ps:试了下用weak指针还是不能释放,不知道是什么原因。)因此还需要进一步改进,正确的写法是用一个新的controller来处理,新的controller再绕用delegate绕回来。

oc代码(正确写法):

  1. @interface ViewController ()<WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler>{
  2. WKWebView * webView;
  3. WKUserContentController* userContentController;
  4. }
  5. @end
  6. @implementation ViewController
  7. #pragma mark - lifeCircle
  8. - (void)viewDidLoad {
  9. [super viewDidLoad];
  10. //配置环境
  11. WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc]init];
  12. userContentController =[[WKUserContentController alloc]init];
  13. configuration.userContentController = userContentController;
  14. webView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, 100, 100) configuration:configuration];
  15. //注册方法
  16. WKDelegateController * delegateController = [[WKDelegateController alloc]init];
  17. delegateController.delegate = self;
  18. [userContentController addScriptMessageHandler:delegateController name:@"sayhello"];
  19. [self.view addSubview:webView];
  20. [webView mas_makeConstraints:^(MASConstraintMaker *make) {
  21. make.left.equalTo(self.view);
  22. make.right.equalTo(self.view);
  23. make.top.equalTo(self.view);
  24. make.bottom.equalTo(self.view);
  25. }];
  26. webView.UIDelegate = self;
  27. webView.navigationDelegate = self;
  28. [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.test.com"]]];
  29. }
  30. - (void)dealloc{
  31. //这里需要注意,前面增加过的方法一定要remove掉。
  32. [userContentController removeScriptMessageHandlerForName:@"sayhello"];
  33. }
  34. #pragma mark - WKScriptMessageHandler
  35. - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
  36. NSLog(@"name:%@\\\\n body:%@\\\\n frameInfo:%@\\\\n",message.name,message.body,message.frameInfo);
  37. }
  38. @end

WKDelegateController代码:

  1. #import <UIKit/UIKit.h>
  2. #import <WebKit/WebKit.h>
  3. @protocol WKDelegate <NSObject>
  4. - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;
  5. @end
  6. @interface WKDelegateController : UIViewController <WKScriptMessageHandler>
  7. @property (weak , nonatomic) id<WKDelegate> delegate;
  8. @end

.m代码:

  1. #import "WKDelegateController.h"
  2. @interface WKDelegateController ()
  3. @end
  4. @implementation WKDelegateController
  5. - (void)viewDidLoad {
  6. [super viewDidLoad];
  7. }
  8. - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
  9. if ([self.delegate respondsToSelector:@selector(userContentController:didReceiveScriptMessage:)]) {
  10. [self.delegate userContentController:userContentController didReceiveScriptMessage:message];
  11. }
  12. }
  13. @end

h5代码:

  1. <html>
  2. <head>
  3. <script>
  4. function say()
  5. {
  6. //前端需要用 window.webkit.messageHandlers.注册的方法名.postMessage({body:传输的数据} 来给native发送消息
  7. window.webkit.messageHandlers.sayhello.postMessage({body: 'hello world!'});
  8. }
  9. </script>
  10. </head>
  11. <body>
  12. <h1>hello world</h1>
  13. <button onclick="say()">say hello</button>
  14. </body>
  15. </html>

打印出的log:

  1. name:sayhello
  2. body:{
  3. body = "hello world!";
  4. }
  5. frameInfo:<WKFrameInfo: 0x7f872060ce20; isMainFrame = YES; request = <NSMutableURLRequest: 0x618000010a30> { URL: http://www.test.com/ }>

注意点

  • addScriptMessageHandler要和removeScriptMessageHandlerForName配套出现,否则会造成内存泄漏。
  • h5只能传一个参数,如果需要多个参数就需要用字典或者json组装。

oc调用JS方法

代码如下:

  1. - (void)webView:(WKWebView *)tmpWebView didFinishNavigation:(WKNavigation *)navigation{
  2. //say()是JS方法名,completionHandler是异步回调block
  3. [webView evaluateJavaScript:@"say()" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
  4. NSLog(@"%@",result);
  5. }];
  6. }

h5代码同上。

  1. 链接:https://www.jianshu.com/p/4fa8c4eb1316

WKWebView使用方法的更多相关文章

  1. WKWebView代理方法解析

    一.前言 上一篇文章已经对WKWebView做了一个简单的介绍,主要对它的一些方法和属性做了一个简单的介绍,今天看一下WKWebView的两个协议:WKNavigationDelegate 和 WKU ...

  2. iOS 8 WKWebView

    首先看看这篇文章,写得很好:http://nshipster.cn/wkwebkit/ 再推荐去看看 iOS_8_by_Tutorials 这本书里的 WKWebView相关章节! 我这里说下自己的简 ...

  3. iOS WKWebView详解

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

  4. iOS 8 WKWebView 知识点

    首先看看这篇文章,写得很好:http://nshipster.cn/wkwebkit/ 再推荐去看看 iOS_8_by_Tutorials 这本书里的 WKWebView相关章节! 我这里说下自己的简 ...

  5. Hybrid App: 对比UIWebView和WebKit实现JavaScript与Native交互

    一.简介 在前面一篇文章中讲到过实现JavaScript与Native交互的方式有一种就是使用原生内嵌webView.在iOS8之前,开发者只能使用苹果提供的UIWebView类来加载URL或者HTM ...

  6. javaSE27天复习总结

    JAVA学习总结    2 第一天    2 1:计算机概述(了解)    2 (1)计算机    2 (2)计算机硬件    2 (3)计算机软件    2 (4)软件开发(理解)    2 (5) ...

  7. lib-flexible 结合 WKWebView 的样式错乱解决方法

    技术栈 lib-flexible 是淘宝的可伸缩方案 WKWebView 是ios8以上支持的网页控件 问题场景 最新公司一个项目使用 lib-flexible 来做移动端的伸缩解决方案,页面在saf ...

  8. 有关wkwebview和UIwebview获取html中的标签方法

    wkwebview方法如下: [webView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id r ...

  9. WKWebView浅析

    原文链接:supermokey WKWebView 一个WKWebView对象展示交互的web内容,例如应用于app内的浏览器.你可以在你的App中使用WKWebView. 综述 Important: ...

随机推荐

  1. matlab批量读取一个文件夹里类似命名的mat文件

    参考网址: Matlab读取同一路径下多个txt或mat文件总结 matlab 批量读取数据文件.mat .dat 整理:matlab批量读入数据文件的方法 首先命名方式体现在只是名字里数字有变化,其 ...

  2. phpexcel 使用说明

    下面是总结的几个使用方法 include 'PHPExcel.php'; include 'PHPExcel/Writer/Excel2007.php'; //或者include 'PHPExcel/ ...

  3. HBase原理和设计

    转载 2016年1月10日:http://www.sysdb.cn/index.php/2016/01/10/hbase_principle/ 简介 架构 数据组织 原理 RS定位 region写入 ...

  4. Canvas 渲染模式

    1. Canvas Canvas Component 是UI布局和渲染的抽象空間,所有的UI都必須在此元素之下(子物件),简单来说 Canvas 就是渲染 UI 的組件. 2. Render Mode ...

  5. ffmpeg推送直播流的技术进展

    首先安装好NGINX并打开服务 然后安装好ffmpeg 然后参考:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=2879051 ...

  6. kettle之linux使用kettle

    Kettle可以在Window.Linux.Unix上运行,数据抽取高效稳定,使用之前需要准备环境. 准备java环境,这里就不赘述了,建议jdk7以上版本. 上传kettle压缩包,并解压,我解压的 ...

  7. php7-编译安装参数

    ./configure \--with-fpm-user=www \--with-fpm-group=www \--prefix=/usr/local/php7 \--with-config-file ...

  8. 影响Arcmap运行效率的因素

    在使用ArcMap的过程中,总觉得ArcMap运行起来非常慢,目前发现了两点原因: 一.渲染太多图斑 比较常见的,我们在打开矢量图层时,Arcmap会自动渲染加载进去的图斑,进行符号化.在渲染的过程中 ...

  9. ccf-命令行选项-201403-3

    分析: 这道题不是很难 用了一个split()函数 核心是: 对命令选项的判断 不要一个字符字符的判断 要一项一项的判断 比如ab:m: 分析步骤 (1) 读取一个字符(2)判断下一步是否有字符,下一 ...

  10. Vue源码之目录结构

    Vue版本:2.6.9 源码结构图 ├─ .circleci // 包含CircleCI持续集成/持续部署工具的配置文件 ├─ .github // 项目相关的说明文档,上面的说明文档就在此文件夹 ├ ...