服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - ios下OC与JS交互之WKWebView

ios下OC与JS交互之WKWebView

2021-03-08 15:16流浪_先生 IOS

本篇文章主要介绍了ios下OC与JS交互之WKWebView,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

上一篇文章我们使用了JavaScriptCore框架重写了之前的示例,iOS8苹果偏爱HTML5,重构了UIWebVIew,给我们带来了WKWebView,使其性能、稳定性、功能大幅度提升,也更好的支持了HTML5的新特性。这篇文章就们就拿WKWebView来小试牛刀

一、WKWebView Framework

WKWebView的14个类与3个协议:

WKBackForwardList: 之前访问过的 web 页面的列表,可以通过后退和前进动作来访问到。

WKBackForwardListItem: webview 中后退列表里的某一个网页。

WKFrameInfo: 包含一个网页的布局信息。

WKNavigation: 包含一个网页的加载进度信息。

WKNavigationAction: 包含可能让网页导航变化的信息,用于判断是否做出导航变化。

WKNavigationResponse: 包含可能让网页导航变化的返回内容信息,用于判断是否做出导航变化。

WKPreferences: 概括一个 webview 的偏好设置。

WKProcessPool: 表示一个 web 内容加载池。

WKUserContentController: 提供使用 JavaScript post 信息和注射 script 的方法。

WKScriptMessage: 包含网页发出的信息。

WKUserScript: 表示可以被网页接受的用户脚本。

WKWebViewConfiguration: 初始化 webview 的设置。

WKWindowFeatures: 指定加载新网页时的窗口属性。

WKWebsiteDataStore: 包含网页数据存储和查找。

WKNavigationDelegate: 提供了追踪主窗口网页加载过程和判断主窗口和子窗口是否进行页面加载新页面的相关方法。

WKUIDelegate: 提供用原生控件显示网页的方法回调。

WKScriptMessageHandler: 提供从网页中收消息的回调方法。

二、WKWebView中的三个代理方法

1. WKNavigationDelegate

该代理提供的方法,可以用来追踪加载过程(页面开始加载、加载完成、加载失败)、决定是否执行跳转。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 页面开始加载时调用
 
- (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;

页面跳转的代理方法有三种,分为(收到跳转与决定是否跳转两种)

?
1
2
3
4
5
6
7
8
9
10
11
// 接收到服务器跳转请求之后调用
 
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation;
 
// 在收到响应后,决定是否跳转
 
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
 
// 在发送请求之前,决定是否跳转
 
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;

2. WKUIDelegate

创建一个新的WKWebView

?
1
2
3
// 创建一个新的WebView
 
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures;

剩下三个代理方法全都是与界面弹出提示框相关的,针对于web界面的三种提示框(警告框、确认框、输入框)分别对应三种代理方法。

?
1
2
3
4
5
6
7
8
9
10
11
// 界面弹出警告框
 
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(void (^)())completionHandler;
 
// 界面弹出确认框
 
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler;
 
// 界面弹出输入框
 
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler;

3. WKScriptMessageHandler

这个协议中包含一个必须实现的方法,这个方法是native与web端交互的关键,它可以直接将接收到的JS脚本转为OC或Swift对象。

?
1
2
3
// 从web界面中接收到一个脚本时调用
 
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;

三、使用WKWebView重写

这里我们和之前的界面做了一点改动,之前OC调用JS的时候是进行弹框处理,这里我在写的时候,很郁闷,方法可以调用过去,但是唯独js的alert方法调用没有效果,所以这里采用了输出到div的形式,并增加了一个clear按钮

WKWebView不支持nib文件,所以这里需要使用代码初始化并加载WebView

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
 
config.preferences.minimumFontSize = 18;
 
 
 
self.wkWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height/2) configuration:config];
 
[self.view addSubview:self.wkWebView];
 
 
 
 
 
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
 
NSURL *baseURL = [[NSBundle mainBundle] bundleURL];
 
[self.wkWebView loadHTMLString:[NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil] baseURL:baseURL];

OC端:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//1. JS调用OC 添加处理脚本
 
[userCC addScriptMessageHandler:self name:@"showMobile"];
 
[userCC addScriptMessageHandler:self name:@"showName"];
 
[userCC addScriptMessageHandler:self name:@"showSendMsg"];
 
 
 
// 在代理方法中处理对应事件
 
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
 
  NSLog(@"%@",NSStringFromSelector(_cmd));
 
  NSLog(@"%@",message.body);
 
 
 
  if ([message.name isEqualToString:@"showMobile"]) {
 
    [self showMsg:@"我是下面的小红 手机号是:18870707070"];
 
  }
 
   
 
  if ([message.name isEqualToString:@"showName"]) {
 
    NSString *info = [NSString stringWithFormat:@"你好 %@, 很高兴见到你",message.body];
 
    [self showMsg:info];
 
  }
 
   
 
  if ([message.name isEqualToString:@"showSendMsg"]) {
 
    NSArray *array = message.body;
 
    NSString *info = [NSString stringWithFormat:@"这是我的手机号: %@, %@ !!",array.firstObject,array.lastObject];
 
    [self showMsg:info];
 
  }
 
}
 
 
 
// 2. native调用js
 
- (IBAction)btnClick:(UIButton *)sender {
 
  if (!self.wkWebView.loading) {
 
    if (sender.tag == 123) {
 
      [self.wkWebView evaluateJavaScript:@"alertMobile()" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
 
        //TODO
 
        NSLog(@"%@ %@",response,error);
 
      }];
 
    }
 
     
 
    if (sender.tag == 234) {
 
      [self.wkWebView evaluateJavaScript:@"alertName('小红')" completionHandler:nil];
 
    }
 
     
 
    if (sender.tag == 345) {
 
      [self.wkWebView evaluateJavaScript:@"alertSendMsg('18870707070','周末爬山真是件愉快的事情')" completionHandler:nil];
 
    }
 
 
 
  } else {
 
    NSLog(@"the view is currently loading content");
 
  }
 
}

JS端:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
function clear() {
 
  document.getElementById('mobile').innerHTML = ''
 
  document.getElementById('name').innerHTML = ''
 
  document.getElementById('msg').innerHTML = ''
 
}
 
 
 
//OC调用JS的方法列表
 
function alertMobile() {
 
  //这里已经调用过来了 但是搞不明白为什么alert方法没有响应
 
  //alert('我是上面的小黄 手机号是:13300001111')
 
  document.getElementById('mobile').innerHTML = '我是上面的小黄 手机号是:13300001111'
 
}
 
 
 
function alertName(msg) {
 
  //alert('你好 ' + msg + ', 我也很高兴见到你')
 
  document.getElementById('name').innerHTML = '你好 ' + msg + ', 我也很高兴见到你'
 
}
 
 
 
function alertSendMsg(num,msg) {
 
  //window.alert('这是我的手机号:' + num + ',' + msg + '!!')
 
  document.getElementById('msg').innerHTML = '这是我的手机号:' + num + ',' + msg + '!!'
 
}
 
 
 
//JS响应方法列表
 
function btnClick1() {
 
  window.webkit.messageHandlers.showMobile.postMessage(null)
 
}
 
 
 
function btnClick2() {
 
  window.webkit.messageHandlers.showName.postMessage('xiao黄')
 
}
 
 
 
function btnClick3() {
 
  window.webkit.messageHandlers.showSendMsg.postMessage(['13300001111', 'Go Climbing This Weekend !!!'])
 
}

四、后记

至此,整个系列的示例已完成,过程中收货颇丰。每篇文章都会对知识点进行总结,在文章末尾给出示例DEMO的地址。

示例DEMO:OC-JS-WKWebView.rar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:http://www.cnblogs.com/markstray/p/5757264.html

延伸 · 阅读

精彩推荐
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28
  • IOSiOS布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04
  • IOS关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01