基本使用方法


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

比较常用的方法:

#pragma mark - lifeCircle
- (void)viewDidLoad {
[super viewDidLoad];
webView = [[WKWebView alloc]init];
[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.baidu.com"]]]; } #pragma mark - WKNavigationDelegate
// 页面开始加载时调用
- (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{ }
// 接收到服务器跳转请求之后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{ }
// 在收到响应后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{ NSLog(@"%@",navigationResponse.response.URL.absoluteString);
//允许跳转
decisionHandler(WKNavigationResponsePolicyAllow);
//不允许跳转
//decisionHandler(WKNavigationResponsePolicyCancel);
}
// 在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{ NSLog(@"%@",navigationAction.request.URL.absoluteString);
//允许跳转
decisionHandler(WKNavigationActionPolicyAllow);
//不允许跳转
//decisionHandler(WKNavigationActionPolicyCancel);
}
#pragma mark - WKUIDelegate
// 创建一个新的WebView
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures{
return [[WKWebView alloc]init];
}
// 输入框
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler{
completionHandler(@"http");
}
// 确认框
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler{
completionHandler(YES);
}
// 警告框
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
NSLog(@"%@",message);
completionHandler();
}

OC与JS交互


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

JS调用OC方法

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

@interface ViewController ()<WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler>{
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];
//注册方法
[userContentController addScriptMessageHandler:self name:@"sayhello"];//注册一个name为sayhello的js方法 [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

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

oc代码(正确写法):

@interface ViewController ()<WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler>{
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 <UIKit/UIKit.h>
#import <WebKit/WebKit.h>
@protocol WKDelegate <NSObject> - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message; @end @interface WKDelegateController : UIViewController <WKScriptMessageHandler> @property (weak , nonatomic) id<WKDelegate> delegate; @end

.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代码:

<html>
<head>
<script>
function say()
{
//前端需要用 window.webkit.messageHandlers.注册的方法名.postMessage({body:传输的数据} 来给native发送消息
window.webkit.messageHandlers.sayhello.postMessage({body: 'hello world!'});
}
</script>
</head>
<body>
<h1>hello world</h1>
<button onclick="say()">say hello</button>
</body> </html>

打印出的log:

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

注意点

  • 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代码同上。

链接: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. Eureka的初识

    在bili看完spring cloud eureka高可用注册中心的视频以后总结: 正常开发中,肯定有一个功能聚集服务中心,将功能方法全部写入其中,也就是一个springboot项目.该服务配置如下: ...

  2. xcode10 出现iPhone has denied the launch request

    一般的处理这里不介绍,只要介绍因为证书的问题导致这个原因的.我的现象是,模拟器可以,iOS12以下设备可以,证书全部更新了一遍,只有一个没更新,还真是那个没更新的问题. 从钥匙串查看自己的证书配置,看 ...

  3. python基础3、4---流程控制、运算符

    1.for循环 和while循环 for 临时变量 in 待遍历的数据: 循环体 (循环体这里一般加break,结束循环,执行else代码) else: 循环不满足条件执行的代码 while  表达式 ...

  4. 转 Mac 下自带的中文输入法不显示汉字提示问题

    原文 https://blog.csdn.net/moxi_wang/article/details/50721326 当时聊天的时候不知道那个手指头按错了什么键 导致Mac自带的中文输入法不能提示显 ...

  5. Hadoop_CDH安装

    ——本文非个人原创,为大牛同事整理,发布于此以备忘 1     CDH5.8安装(2018年4月19日) 1.1   物理服务器注意事项 (1)把raid都去掉了,每个物理盘都用raid0创建一个虚拟 ...

  6. 实验三 CC2530平台上CC2530平台上定时器组件的

    实验三 CC2530平台上CC2530平台上定时器组件的TinyOS编程 实验目的: 加深和巩固学生对于TinyOS编程方法的理解和掌握 让学生初步掌握CC2530定时器的PWM功能,及其TinyOS ...

  7. 安装grub到U盘分区,实现多系统引导

    目录 1.分区工具及分区类型 1.1 显示分区表和分区信息 1.1.1 fdisk -l 1.1.2 gdisk -l 1.1.3 parted -l 1.2 常见分区类型 1.3 分区样例 1.3. ...

  8. 学习笔记CB008:词义消歧、有监督、无监督、语义角色标注、信息检索、TF-IDF、隐含语义索引模型

    词义消歧,句子.篇章语义理解基础,必须解决.语言都有大量多种含义词汇.词义消歧,可通过机器学习方法解决.词义消歧有监督机器学习分类算法,判断词义所属分类.词义消歧无监督机器学习聚类算法,把词义聚成多类 ...

  9. 连接管理 与 Netty 心跳机制

    一.前言 踏踏实实,动手去做,talk is cheap, show me the code.先介绍下基础知识,然后做个心跳机制的Demo. 二.连接 长连接:在整个通讯过程,客户端和服务端只用一个S ...

  10. PymongoDB_study

    import pymongo client = pymongo.MongoClient(host='localhost',port=27017)#连接数据库 #db = client.test#指定数 ...