iOS和JS交互教程之WKWebView-协议拦截详解
前⾔
由于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代码:
//! 登录按钮
<button onclick = "login()" style = "font-size: 18px;">登录</button>
//! 登录
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代码:
#pragma mark - WKNavigationDelegate
//! WKWeView在每次加载请求前会调⽤此⽅法来确认是否进⾏请求跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)na
vigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {  if ([quest.URL.scheme caseInsensitiveCompare:@"jsToOc"] == NSOrderedSame) {
[WKWebViewInterceptController quest.URL.host quest.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还可以将quest.URL.host看作JS想调⽤的⽅法名,将
PS2:在-webView:decidePolicyForNavigationAction:decisionHandler:⽅法中⼀定要调⽤decisionHandler回调来制定允许请求跳转
WKNavigationActionPolicyAllow或者不允许跳转WKNavigationActionPolicyAllow,不然会崩溃。
⼆、iOS调⽤JS:
实现逻辑:点击iOS的登录按钮,iOS将登录成功后的token数据传递给JS,JS将收到的数据展⽰出来。
实现效果:
iOS调⽤JS实现效果
iOS代码:
//! 登录按钮
UIBarButtonItem *loginBtnItem = [[UIBarButtonItem alloc] initWithTitle:@"登录" style:UIBarButtonItemStylePlain target:self action:@selector(login:)];
self.navigationItem.rightBarButtonItems = @[loginBtnItem];
//! 登录⽅法
- (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代码:
//! iOS调⽤JS⼊⼝
function ocToJs(action, params) {
}
//! iOS调⽤JS数据显⽰框
<div id = "returnValue" style = "font-size: 18px; border: 1px dotted; height: 50px;"> </div>
view ui框架
实现原理:
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的标题。
//! WKWebView在每次加载请求完成后会调⽤此⽅法
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
[webView evaluateJavaScript:@"document.title" completionHandler:^(NSString *title, NSError *error) {
self.title = title;
}];
}
可从QiShare的Github获取()
总结
以上就是这篇⽂章的全部内容了,希望本⽂的内容对⼤家的学习或者⼯作具有⼀定的参考学习价值,如果有疑问⼤家可以留⾔交流,谢谢⼤家对的⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。