wkwebview执行js 什么时候执行js

WKWebView 的使用浅析
WKWebView相对于UIWebView强大了很多,内存的消耗相对少了,所提供的接口也丰富了。
现在谈一谈WKWebView的基本使用
1. navigationDelegate
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { // 类似UIWebView的 -webViewDidStartLoad:
NSLog(@&didStartProvisionalNavigation&);
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
NSLog(@&didCommitNavigation&);
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { // 类似 UIWebView 的 -webViewDidFinishLoad:
NSLog(@&didFinishNavigation&);
[self resetControl];
if (webView.title.length & 0) {
self.title = webView.
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
// 类似 UIWebView 的- webView:didFailLoadWithError:
NSLog(@&didFailProvisionalNavigation&);
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
decisionHandler(WKNavigationResponsePolicyAllow);
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
// 类似 UIWebView 的 -webView: shouldStartLoadWithRequest: navigationType:
NSLog(@&4.%@&,navigationAction.request);
NSString *url = [navigationAction.request.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
decisionHandler(WKNavigationActionPolicyAllow);
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler {
2.UIDelegate
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
// 接口的作用是打开新窗口委托
[self createNewWebViewWithURL:webView.URL.absoluteString config:configuration];
return currentSubView.webV
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)())completionHandler
// js 里面的alert实现,如果不实现,网页的alert函数无效
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@&确定&
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
completionHandler();
[self presentViewController:alertController animated:YES completion:^{}];
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler {
js 里面的alert实现,如果不实现,网页的alert函数无效
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@&确定&
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
completionHandler(YES);
[alertController addAction:[UIAlertAction actionWithTitle:@&取消&
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action){
completionHandler(NO);
[self presentViewController:alertController animated:YES completion:^{}];
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *))completionHandler {
completionHandler(@&Client Not handler&);
WKWebView 执行脚本方法
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^)(id, NSError *))completionH
completionHandler 拥有两个参数,一个是返回错误,一个可以返回执行脚本后的返回值
WKWebView 的Cookie问题
UIWebView 中会自动保存Cookie,如果登录了一次,下次再次进入的时候,会记住登录状态
而在WKWebView中,并不会这样,WKWebView在初始化的时候有一个方法
- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
通过这个方法,设置 configuration 让WKWebView知道登录状态,configuration 可以通过已有的Cookie进行设置,也可以通过保存上一次的configuration进行设置
WKWebView * webView = /*set up your webView*/&
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@&/index.html&]];&
[request addValue:@&TeskCookieKey1=TeskCookieValue1;TeskCookieKey2=TeskCookieValue2;& forHTTPHeaderField:@&Cookie&];&
// use stringWithFormat: in the above line to inject your values programmatically&
[webView loadRequest:request];&
[objc] view plain copy print?在CODE上查看代码片派生到我的代码片
WKUserContentController* userContentController = WKUserContentController.&
WKUserScript * cookieScript = [[WKUserScript alloc]&&
&&& initWithSource: @&document.cookie = 'TeskCookieKey1=TeskCookieValue1';document.cookie = 'TeskCookieKey2=TeskCookieValue2';&&
&&& injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];&
// again, use stringWithFormat: in the above line to inject your values programmatically&
[userContentController addUserScript:cookieScript];&
WKWebViewConfiguration* webViewConfig = WKWebViewConfiguration.&
webViewConfig.userContentController = userContentC&
WKWebView * webView = [[WKWebView alloc] initWithFrame:CGRectMake(/*set your values*/) configuration:webViewConfig];&
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467142',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'上一篇专门讲解了WKWebView相关的所有类、代理的所有API。那么本篇讲些什么呢?当然是实战了!
本篇文章教大家如何使用WKWebView去实现常用的一些API操作。当然,也会有如何与JS交互的实战。
如果还没有阅读过,请先阅读,不然有可能看不懂下面所讲的内容。
通过本篇文章,至少可以学习到:
OC如何给JS注入对象及JS如何给IOS发送数据
JS调用alert、confirm、prompt时,不采用JS原生提示,而是使用iOS原生来实现
如何***web内容加载进度、是否加载完成
如何处理去跨域问题
创建配置类
在创建WKWebView之前,需要先创建配置对象,用于做一些配置:
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
配置偏好设置
偏好设置也没有必须去修改它,都使用默认的就可以了,除非你真的需要修改它:
// 设置偏好设置
config.preferences = [[WKPreferences alloc] init];
// 默认为0
config.preferences.minimumFontSize = 10;
// 默认认为YES
config.preferences.javaScriptEnabled = YES;
// 在iOS上默认为NO,表示不能自动通过窗口打开
config.preferences.javaScriptCanOpenWindowsAutomatically = NO;
配置web内容处理池
其实我们没有必要去创建它,因为它根本没有属性和方法:
// web内容处理池,由于没有属性可以设置,也没有方法可以调用,不用手动创建
config.processPool = [[WKProcessPool alloc] init];
配置Js与Web内容交互
WKUserContentController是用于给JS注入对象的,注入对象后,JS端就可以使用:
window.webkit.messageHandlers.&name&.postMessage(&messageBody&)
来调用发送数据给iOS端,比如:
window.webkit.messageHandlers.AppModel.postMessage({body: '传数据'});
AppModel就是我们要注入的名称,注入以后,就可以在JS端调用了,传数据统一通过body传,可以是多种类型,只支持NSNumber, NSString, NSDate, NSArray,NSDictionary, and NSNull类型。
下面我们配置给JS的main frame注入AppModel名称,对于JS端可就是对象了:
// 通过JS与webview内容交互
config.userContentController = [[WKUserContentController alloc] init];
// 注入JS对象名称AppModel,当JS通过AppModel来调用时,
// 我们可以在WKScriptMessageHandler代理中接收到
[config.userContentController addScriptMessageHandler:self name:@"AppModel"];
当JS通过AppModel发送数据到iOS端时,会在代理中收到:
#pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController
&&&&&&didReceiveScriptMessage:(WKScriptMessage *)message {
&&if ([message.name isEqualToString:@"AppModel"]) {
&&&&// 打印所传过来的参数,只支持NSNumber, NSString, NSDate, NSArray,
&&&&// NSDictionary, and NSNull类型
&&&&NSLog(@"%@", message.body);
所有JS调用iOS的部分,都只可以在此处使用哦。当然我们也可以注入多个名称(JS对象),用于区分功能。
创建WKWebView
通过唯一的默认构造器来创建对象:
self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&configuration:config];
[self.view addSubview:self.webView];&&&&&&&&&&&&&&&&&&&&&&
加载H5页面
NSURL *path = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"html"];
[self.webView loadRequest:[NSURLRequest requestWithURL:path]];
如果需要处理web导航条上的代理处理,比如链接是否可以跳转或者如何跳转,需要设置代理;而如果需要与在JS调用alert、confirm、prompt函数时,通过JS原生来处理,而不是调用JS的alert、confirm、prompt函数,那么需要设置UIDelegate,在得到响应后可以将结果反馈到JS端:
// 导航代理
self.webView.navigationDelegate = self;
// 与webview UI交互代理
self.webView.UIDelegate = self;
添加对WKWebView属性的***
WKWebView有好多个支持KVO的属性,这里只是***loading、title、estimatedProgress属性,分别用于判断是否正在加载、获取页面标题、当前页面载入进度:
// 添加KVO***
[self.webView addObserver:self
&&&&&&&&&&&& forKeyPath:@"loading"
&&&&&&&&&&&&&&&&options:NSKeyValueObservingOptionNew
&&&&&&&&&&&&&&&&context:nil];
[self.webView addObserver:self
&&&&&&&&&&&& forKeyPath:@"title"
&&&&&&&&&&&&&&&&options:NSKeyValueObservingOptionNew
&&&&&&&&&&&&&&&&context:nil];
[self.webView addObserver:self
&&&&&&&&&&&& forKeyPath:@"estimatedProgress"
&&&&&&&&&&&&&&&&options:NSKeyValueObservingOptionNew
&&&&&&&&&&&&&&&&context:nil];
然后我们就可以实现KVO处理方法,在loading完成时,可以注入一些JS到web中。这里只是简单地执行一段web中的JS函数:
#pragma mark - KVO
- (void)observeValueForKeyPath:(NSString *)keyPath
&&&&&&&&&&&&&&&&&&&&&&ofObject:(id)object
&&&&&&&&&&&&&&&&&&&&&&&&change:(NSDictionary&NSString *,id& *)change
&&&&&&&&&&&&&&&&&&&&&& context:(void *)context {
&&if ([keyPath isEqualToString:@"loading"]) {
&&&&NSLog(@"loading");
&&} else if ([keyPath isEqualToString:@"title"]) {
&&&&self.title = self.webView.title;
&&} else if ([keyPath isEqualToString:@"estimatedProgress"]) {
&&&&NSLog(@"progress: %f", self.webView.estimatedProgress);
&&&&self.progressView.progress = self.webView.estimatedProgress;
&&// 加载完成
&&if (!self.webView.loading) {
&&&&// 手动调用JS代码
&&&&// 每次页面完成都弹出来,大家可以在测试时再打开
&&&&NSString *js = @"callJsAlert()";
&&&&[self.webView evaluateJavaScript:js completionHandler:^(id _Nullable response, NSError * _Nullable error) {
&&&&&&NSLog(@"response: %@ error: %@", response, error);
&&&&&&NSLog(@"call js alert by native");
&&&&[UIView animateWithDuration:0.5 animations:^{
&&&&&&self.progressView.alpha = 0;
WKUIDelegate
与JS原生的alert、confirm、prompt交互,将弹出来的实际上是我们原生的窗口,而不是JS的。在得到数据后,由原生传回到JS:
#pragma mark - WKUIDelegate
- (void)webViewDidClose:(WKWebView *)webView {
&&&& NSLog(@"%s", __FUNCTION__);
// 在JS端调用alert函数时,会触发此代理方法。
// JS端调用alert时所传的数据可以通过message拿到
// 在原生得到结果后,需要回调JS,是通过completionHandler回调
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
&&NSLog(@"%s", __FUNCTION__);
&&UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"alert" message:@"JS调用alert" preferredStyle:UIAlertControllerStyleAlert];
&&[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
&&&&completionHandler();
&&[self presentViewController:alert animated:YES completion:NULL];
&&NSLog(@"%@", message);
// JS端调用confirm函数时,会触发此方法
// 通过message可以拿到JS端所传的数据
// 在iOS端显示原生alert得到YES/NO后
// 通过completionHandler回调给JS端
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler {
&&NSLog(@"%s", __FUNCTION__);
&&UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"confirm" message:@"JS调用confirm" preferredStyle:UIAlertControllerStyleAlert];
&&[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
&&&&completionHandler(YES);
&&[alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
&&&&completionHandler(NO);
&&[self presentViewController:alert animated:YES completion:NULL];
&&NSLog(@"%@", message);
// JS端调用prompt函数时,会触发此方法
// 要求输入一段文本
// 在原生输入得到文本内容后,通过completionHandler回调给JS
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler {
&&NSLog(@"%s", __FUNCTION__);
&&NSLog(@"%@", prompt);
&&UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"textinput" message:@"JS调用输入框" preferredStyle:UIAlertControllerStyleAlert];
&&[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
&&&&textField.textColor = [UIColor redColor];
&&[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
&&&&completionHandler([[alert.textFields lastObject] text]);
&&[self presentViewController:alert animated:YES completion:NULL];
WKNavigationDelegate
如果需要处理web导航操作,比如链接跳转、接收响应、在导航开始、成功、失败等时要做些处理,就可以通过实现相关的代理方法:
#pragma mark - WKNavigationDelegate
// 请求开始前,会先调用此代理方法
// 与UIWebView的
// - (BOOL)webView:(UIWebView *)webView
// shouldStartLoadWithRequest:(NSURLRequest *)request
// navigationType:(UIWebViewNavigationType)navigationT
// 类型,在请求先判断能不能跳转(请求)
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
&&NSString *hostname = navigationAction.request.URL.host.lowercaseString;
&&if (navigationAction.navigationType == WKNavigationTypeLinkActivated
&&&&&&&& ![hostname containsString:@"."]) {
// 对于跨域,需要手动跳转
&&&&[[UIApplication sharedApplication] openURL:navigationAction.request.URL];
&&&&// 不允许web内跳转
&&&&decisionHandler(WKNavigationActionPolicyCancel);
&&} else {
&&&&self.progressView.alpha = 1.0;
&&&&decisionHandler(WKNavigationActionPolicyAllow);
&&&&NSLog(@"%s", __FUNCTION__);
// 在响应完成时,会回调此方法
// 如果设置为不允许响应,web内容就不会传过来
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
&&decisionHandler(WKNavigationResponsePolicyAllow);
&&NSLog(@"%s", __FUNCTION__);
// 开始导航跳转时会回调
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation {
&&&&NSLog(@"%s", __FUNCTION__);
// 接收到重定向时会回调
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation {
&&&&NSLog(@"%s", __FUNCTION__);
// 导航失败时会回调
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
&&&&NSLog(@"%s", __FUNCTION__);
// 页面内容到达main frame时回调
- (void)webView:(WKWebView *)webView didCommitNavigation:(null_unspecified WKNavigation *)navigation {
&&&&NSLog(@"%s", __FUNCTION__);
// 导航完成时,会回调(也就是页面载入完成了)
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation {
&&&&NSLog(@"%s", __FUNCTION__);
// 导航失败时会回调
- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
// 对于HTTPS的都会触发此代理,如果不要求验证,传默认就行
// 如果需要***验证,与使用AFN进行HTTPS***验证是一样的
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *__nullable credential))completionHandler {
&&&&NSLog(@"%s", __FUNCTION__);
&&completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
// 9.0才能使用,web内容处理中断时会触发
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
&&&&NSLog(@"%s", __FUNCTION__);
&!DOCTYPE html&
&&&&&title&iOS and Js&/title&
&&&&&style type="text/css"&
&&&&&&&&font-size: 40px;
&&&&&/style&
&&&&&div style="margin-top: 100px"&
&&&&&&&h1&Test how to use objective-c call js&/h1&&br/&
&&&&&&&div&&input type="button" value="call js alert" onclick="callJsAlert()"&&/div&
&&&&&&&br/&
&&&&&&&div&&input type="button" value="Call js confirm" onclick="callJsConfirm()"&&/div&&br/&
&&&&&/div&
&&&&&&&div&&input type="button" value="Call Js prompt " onclick="callJsInput()"&&/div&&br/&
&&&&&&&div&Click me here: &a href=""&Jump to Baidu&/a&&/div&
&&&&&/div&
&&&&&div id="SwiftDiv"&
&&&&&&&span id="jsParamFuncSpan" style="color: font-size: 50"&&/span&
&&&&&/div&
&&&&&script type="text/javascript"&
&&&&&&function callJsAlert() {
&&&&&&&&alert('Objective-C call js to show alert');
&&&&&&&&window.webkit.messageHandlers.AppModel.postMessage({body: 'call js alert in js'});
&&&&function callJsConfirm() {
&&&&&&if (confirm('confirm', 'Objective-C call js to show confirm')) {
&&&&&&&&document.getElementById('jsParamFuncSpan').innerHTML
&&&&&&&&= 'true';
&&&&&&} else {
&&&&&&&&document.getElementById('jsParamFuncSpan').innerHTML
&&&&&&&&= 'false';
&&&&&&// AppModel是我们所注入的对象
&&&&&&window.webkit.messageHandlers.AppModel.postMessage({body: 'call js confirm in js'});
&&&&function callJsInput() {
&&&&&&var response = prompt('Hello', 'Please input your name:');
&&&&&&document.getElementById('jsParamFuncSpan').innerHTML = response;
&&&&&& // AppModel是我们所注入的对象
&&&&&&window.webkit.messageHandlers.AppModel.postMessage({body: response});
&& &/script&
阅读(...) 评论()还在用UIWebView?何不试试WKWebView - 简书
下载简书移动应用
写了257026字,被2556人关注,获得了5783个喜欢
还在用UIWebView?何不试试WKWebView
WKWebView是苹果在 iOS 8 中引入的新组件,目的是给出一个新的高性能的 Web View 解决方案,摆脱过去 UIWebView 的老旧笨重特别是内存占用量巨大的问题。WKWebView使用Nitro JavaScript引擎,这意味着所有第三方浏览器运行JavaScript将会跟safari一样快。
简单代码实现
@interface ViewController () &WKNavigationDelegate&
@property (nonatomic, strong) WKWebView *webV
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
self.webView.allowsBackForwardNavigationGestures = YES;
self.webView.navigationDelegate =
[self.view addSubview:self.webView];
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]]];
WKWebView优点
1.将浏览器内核渲染进程提取出 App,由系统进行统一管理,这减少了相当一部分的性能损失。
2.js 可以直接使用已经事先注入 js runtime 的 js 接口给 Native 层传值,不必再通过苦逼的 iframe 制造页面刷新再解析自定义协议的奇怪方式。
3.支持高达 60 fps 的滚动刷新率,内置了手势探测。
WKWebView类比UIWebView的API
第一、WKWebView增加的属性和方法
增加的属性:1.estimatedProgress 加载进度条。
2.backForwardList 表示historyList
3.WKWebViewConfiguration *初始化webview的配置
增加的方法:
- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration 初始化
- (nullable WKNavigation *)goToBackForwardListItem:(WKBackForwardListItem *)跳到历史的某个页面
第二、相同的属性和方法
goBack、goForward、canGoBack、canGoForward、stopLoading、loadRequest、scrollView
第三、被删去的属性和方法:
1.在跟js交互时,我们使用这个API,目前WKWebView完档没有给出实现类似功能的API
- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)
2.无法设置缓存在UIWebView,UIWebView可以使用NSURLCache缓存,通过setSharedURLCache可以设置成我们自己的缓存,但WKWebView不支持NSURLCache
第四、delegate方法的不同
UIWebView支持的代理是UIWebViewDelegate,WKWebView支持的代理是WKNavigationDelegate和WKUIDelegate。WKNavigationDelegate主要实现了涉及到导航跳转方面的回调方法,WKUIDelegate主要实现了涉及到界面显示的回调方法:如WKWebView的改变和js相关内容。
具体来说WKNavigationDelegate除了有开始加载、加载成功、加载失败的API外,还具有额外的三个代理方法:
1.- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation
这个代理是服务器redirect时调用
2.- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
这个代理方法表示当客户端收到服务器的响应头,根据response相关信息,可以决定这次跳转是否可以继续进行。
3.- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
根据webView、navigationAction相关信息决定这次跳转是否可以继续进行,这些信息包含HTTP发送请求,如头部包含User-Agent,Accept
WKWebView VS UIWebView
比UIWebView提升差不多一倍的, 内存使用上面,反而还少了一半。缺点:
WKWebView 不支持缓存 和
NSURLProtocol 拦截
1.WKWebView 执行脚本方法
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^)(id, NSError *))completionH
completionHandler 拥有两个参数,一个是返回错误,一个可以返回执行脚本后的返回值
2.WKWebView 的Cookie问题
UIWebView 中会自动保存Cookie,如果登录了一次,下次再次进入的时候,会记住登录状态,而在WKWebView中,并不会这样,WKWebView在初始化的时候有一个方法
- (instancetype)initWithFrame:(CGRect)frame configuration:(WKWebViewConfiguration *)configuration
通过这个方法,设置 configuration 让WKWebView知道登录状态,configuration 可以通过已有的Cookie进行设置,也可以通过保存上一次的configuration进行设置。
WKUserContentController* userContentController = WKUserContentController.
WKUserScript * cookieScript = [[WKUserScript alloc] initWithSource: @"document.cookie ='TeskCookieKey1=TeskCookieValue1';document.cookie = 'TeskCookieKey2=TeskCookieValue2';"injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
[userContentController addUserScript:cookieScript];
WKWebViewConfiguration* webViewConfig = WKWebViewConfiguration.
webViewConfig.userContentController = userContentC
WKWebView * webView = [[WKWebView alloc] initWithFrame:CGRectMake(/*set your values*/) configuration:webViewConfig];
3.显示弹窗
在 UIWebView 里,js 的 alert() 弹窗会自动以系统弹窗的形式展示,但是 WKWebview 把这个接口也暴露给了我们,让我们自己 handle js 传来的 alert()。下面我们将自己写代码 handle 住这个事件,并展示为系统弹窗。
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)())completionHandler
// js 里面的alert实现,如果不实现,网页的alert函数无效
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"确定"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
completionHandler();
[self presentViewController:alertController animated:YES completion:^{}];
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler {
// confirm提示框风格 js 里面的alert实现,如果不实现,网页的alert函数无效
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:message
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:[UIAlertAction actionWithTitle:@"确定"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
completionHandler(YES);
[alertController addAction:[UIAlertAction actionWithTitle:@"取消"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action){
completionHandler(NO);
[self presentViewController:alertController animated:YES completion:^{}];
使用 Safari 自带的 Web View 调试工具执行 alert() 函数:
更多有趣好玩的事情,我们后续再聊。
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
表示没看懂,却觉得高大上的感觉
WKWebView 是自己写的类???
WKWebView 的Cookie问题,这部分,我没太清楚WKWebView到底是需要自己写代码缓存cookie,还是说WKWebView本身缓存了,只是在初始化的时候,你可以决定是用cookie配置还是用保存的configure去配置?
决定跳转url是a链接且含有_blank, 貌似不含_blank的并不能拦截?
一大堆坑呀,本地资源内置,进程释放白屏,探索可以,实际项目少碰呀
但是只能ios 8以上 这点 我就不能接受了
WKWebView 的Cookie问题, 能行吗?我怎么测试都不行呀?有成功的代码例子吗?谢谢
wkWebView 里面没有 stringByEvaluatingJavaScriptFromString 我想要让里面的一小块内容不显示 有什么办法替换嘛
被以下专题收入,发现更多相似内容:
玩转简书的第一步,从这个专题开始。
想上首页热门榜么?好内容想被更多人看到么?来投稿吧!如果被拒也不要灰心哦~入选文章会进一个队...
? 136090人关注
【最新投稿方式】
为了保证专题文章的质量,暂时关闭投稿申请,改为【私信文章链接】给本专题的管理员 (花前月下) (判若...
? 7292人关注
学习从点滴开始 !
(PS: 拒绝部分投稿的文章仅仅是由于专题内已收录相关知识点的文章, 并非是投稿的文章技术含量不够好, 望谅解.)
? 5545人关注
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:

参考资料

 

随机推荐