前言
由于xcode8发布之后,编译器开始不支持ios 7了,这样我们的app也改为最低支持ios 8.0,既然需要与web交互,那自然也就选择使用了 ios 8.0之后 才推出的新控件 wkwebview.
相比与 uiwebview, wkwebview 存在很多优势:
- 支持更多的html5的特性
- 高达60fps滚动刷新频率与内置手势
- 与safari相容的javascript引擎
- 在性能、稳定性方面有很大提升占用内存更少 协议方法及功能都更细致
- 可获取加载进度等。
先解释下标题:“ios与js交互”。ios指ios原生代码(文章只有oc示例),js指web前端(不单指javascript),交互指js调用ios和ios调用js。
本文介绍通过 wkwebview协议拦截的方式实现ios与js交互。
wkwebview是apple在ios8推出的webkit框架中的负责网页的渲染与展示的类,相比uiwebview速度更快,占用内存更少,支持更多的html特性。
一、js调用ios:
实现逻辑:点击js的登录按钮,js将登录成功后的token数据传递给ios,ios将收到的数据展示出来。
实现效果:
js调用ios实现效果
js代码:
1
2
|
//! 登录按钮 <button onclick = "login()" style = "font-size: 18px;" >登录</button> |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
//! 登录 function login() { var token = "js_tokenstring" ; loginsucceed(token); } //! 登录成功 function loginsucceed(token) { var action = "loginsucceed" ; jstooc(action, token); } //! js调用oc入口 function jstooc(action, params) { var url = "jstooc://" + action + "?" + params; loadurl(url); } //! 加载url function loadurl(url) { window.location.href = url; } |
ios代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#pragma mark - wknavigationdelegate //! wkweview在每次加载请求前会调用此方法来确认是否进行请求跳转 - ( void )webview:(wkwebview *)webview decidepolicyfornavigationaction:(wknavigationaction *)navigationaction decisionhandler:( void (^)(wknavigationactionpolicy))decisionhandler { if ([navigationaction.request.url.scheme caseinsensitivecompare:@ "jstooc" ] == nsorderedsame) { [wkwebviewinterceptcontroller showalertwithtitle:navigationaction.request.url.host message:navigationaction.request.url.query cancelhandler:nil]; decisionhandler(wknavigationactionpolicycancel); } else { decisionhandler(wknavigationactionpolicyallow); } } |
实现原理:
1、js与ios约定好jstooc协议,用作js在调用ios时url的scheme;
2、js在登录成功后加载含有token数据的url: (jstooc://loginsucceed?js_tokenstring);
3、ios的wkwebview在请求跳转前会调用-webview:decidepolicyfornavigationaction:decisionhandler:方法来确认是否允许跳转;
4、ios在此方法内截取jstooc协议获取js传过来的数据,用uialertcontroller显示出来,并通过decisionhandler不允许此请求跳转。
ps1:除了显示截取到的数据,ios还可以将navigationaction.request.url.host看作js想调用的方法名,将navigationaction.request.url.query看作该方法的参数集,从而体现出js调用ios的概念。
ps2:在-webview:decidepolicyfornavigationaction:decisionhandler:方法中一定要调用decisionhandler回调来制定允许请求跳转wknavigationactionpolicyallow或者不允许跳转wknavigationactionpolicyallow,不然会崩溃。
二、ios调用js:
实现逻辑:点击ios的登录按钮,ios将登录成功后的token数据传递给js,js将收到的数据展示出来。
实现效果:
ios调用js实现效果
ios代码:
1
2
3
|
//! 登录按钮 uibarbuttonitem *loginbtnitem = [[uibarbuttonitem alloc] initwithtitle:@ "登录" style:uibarbuttonitemstyleplain target:self action:@selector(login:)]; self.navigationitem.rightbarbuttonitems = @[loginbtnitem]; |
1
2
3
4
5
6
7
|
//! 登录方法 - ( void )login:(id)sender { dispatch_after(dispatch_time(dispatch_time_now, (int64_t)(0.5 * nsec_per_sec)), dispatch_get_main_queue(), ^{ [self.webview evaluatejavascript:@ "octojs('loginsucceed', 'oc_tokenstring')" completionhandler:^(id response, nserror *error) {}]; }); } |
js代码:
1
2
3
4
|
//! ios调用js入口 function octojs(action, params) { document.getelementbyid( "returnvalue" ).innerhtml = action + '?' + params; } |
1
2
|
//! ios调用js数据显示框 < div id = "returnvalue" style = "font-size: 18px; border: 1px dotted; height: 50px;" > </ div > |
实现原理:
1、ios与js约定好octojs方法,用作ios在调用js时的入口方法;
2、ios在登录成功后以loginsucceed和oc_tokenstring为参数拼接js代码octojs('loginsucceed', 'oc_tokenstring');
3、ios使用wkwebview的-evaluatejavascript:completionhandler:方法执行拼接好的js代码;
3、js在octojs方法中将ios传过来的数据显示在div元素中;
4、ios通过completionhandler收到js中octojs方法的回调。
ps:wkwebview的-evaluatejavascript:completionhandler:方法可以执行js代码。但只有在整个webview加载完成之后调用此方法才会有响应。比如:我们可以通过如下方式获取js的标题。
1
2
3
4
5
6
7
|
//! wkwebview在每次加载请求完成后会调用此方法 - ( void )webview:(wkwebview *)webview didfinishnavigation:(wknavigation *)navigation { [webview evaluatejavascript:@ "document.title" completionhandler:^(nsstring *title, nserror *error) { self.title = title; }]; } |
可从qishare的github获取工程源码
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。
原文链接:https://www.jianshu.com/p/e23aa25d7514