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 *)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代码:

//! 登录按钮
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) {
 document.getElementById("returnValue").innerHTML = action + '?' + params;
}
//! 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的标题。

//! WKWebView在每次加载请求完成后会调用此方法
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {

  [webView evaluateJavaScript:@"document.title" completionHandler:^(NSString *title, NSError *error) {
    self.title = title;
  }];
}

可从QiShare的Github获取工程源码(本地下载)

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • Swift使用WKWebView在iOS应用中调用Web的方法详解

    自从iOS8开始,Apple引入了WKWebView欲代替UIWebView.相比而言,WKWebView消耗内从更少,功能也更加强大.让我们来看看WKWebView怎么使用吧! 0.初始化 (1)首先需要引入WebKit库 复制代码 代码如下: #import <WebKit/WebKit.h> (2)初始化方法分为以下两种 复制代码 代码如下: // 默认初始化 - (instancetype)initWithFrame:(CGRect)frame; // 根据对webview的相关配置,

  • iOS11 WKWebView 无法加载内容的解决方法

    问题描述: iOS9和iOS10用WKWebView加载URL都没有问题,iOS11却是一片空白 可能是用了 NSMutableURLRequest ,iOS11貌似不支持 NSMutableURLRequest ,无论是用 UIWebView 还是 WKWebView ,都不支持 NSMutableURLRequest 解决方法参考 if #available(iOS 11, *) { let request = NSURLRequest.init(url: URL.init(string:

  • iOS11 WKWebView内容过滤规则详解

    WKWebView中新增了一个功能,可以对WebView的内容添加一些自定义的过滤规则.这个功能原来在 Safari Extension 中被引入,从 11 开始同样适用于WKWebView. 使用方法 原理上就是提供一个 JSON 给 WebKit,这个 JSON 包括内容的触发规则(trigger)和对应的处理方式(action).比如: [{ "trigger": { "url-filter": ".*" }, "action&q

  • iOS中WKWebView的一些特殊使用总结

    前言 现在大部分的app只支持iOS8以上的系统了,在接入H5时可以只管最新的WKWebView了. WKWebView的优势 性能高,稳定性好,占用的内存比较小, 支持JS交互 支持HTML5 新特性 可以添加进度条(然并卵,不好用,还是习惯第三方的). 支持内建手势, 据说高达60fps的刷新频率(不卡) 本文将给大家总结下iOS中WKWebView的一些特殊使用,下面话不多说了,来一起看看详细的介绍吧 WKWebView 加载本地网页的方式 1.直接加载字符串 - (void)loadHT

  • ios下OC与JS交互之WKWebView

    上一篇文章我们使用了JavaScriptCore框架重写了之前的示例,iOS8苹果偏爱HTML5,重构了UIWebVIew,给我们带来了WKWebView,使其性能.稳定性.功能大幅度提升,也更好的支持了HTML5的新特性.这篇文章就们就拿WKWebView来小试牛刀 一.WKWebView Framework WKWebView的14个类与3个协议: WKBackForwardList: 之前访问过的 web 页面的列表,可以通过后退和前进动作来访问到. WKBackForwardListIt

  • iOs迁至WKWebView跨过的一些坑

    前言 在iOS中有两种网页视图可以加载网页除了系统的那个控制器.一种是UIWebView,另一种是WKWebView,其实WKWebView就是想替代UIWebView的,因为我们都知道UIWebView非常占内存等一些问题,但是现在很多人还在使用UIWebView这是为啥呢?而且官方也宣布在iOS12中废弃了UIWebView让我们尽快使用WKWebView.其实也就是这些东西:**页面尺寸问题.JS交互.请求拦截.cookie带不上的问题.**所以有时想要迁移还得解决这些问题,所以还是很烦的

  • IOS中UIWebView、WKWebView之JS交互

    做客户端开发,肯定避免不了JS交互,于是自己对苹果接口做了个简易封装: JSExport-->UIWebView+Interaction.WKScriptMessageHandler -->WKWebView+Interaction以备以后使用. 代码非常简洁,见这里:https://github.com/V5zhou/JSInteraction.git 旧方式 旧的交互方式有通过UIWebViewDelegate实现的:JS与客户端定义好跳转页面参数,在将要跳转时捕获关键字,然后处理业务.

  • 简单说说iOS之WKWebView的用法小结

    WKWebView的优势 性能高,稳定性好,占用的内存比较小, 支持JS交互 支持HTML5 新特性 可以添加进度条(然并卵,不好用,还是习惯第三方的). 支持内建手势, 据说高达60fps的刷新频率(不卡) 1.Xcode新建My.html文件,自定义html内容,主要代码如下: (1)标签为UI样式(写了简单的JS代码,目的用于讲解交互) (2)onClick为JS事件,当JS想给OC传递参数时,采用如下代码:window.webkit.messageHandlers.<方法名>.post

  • iOS11 WKWebView问题汇总

    问题一描述: iOS9和iOS10用WKWebView加载URL都没有问题,iOS11却是一片空白 可能是用了NSMutableURLRequest,iOS11貌似不支持NSMutableURLRequest,无论是用UIWebView还是WKWebView,都不支持NSMutableURLRequest 解决方法参考 if #available(iOS 11, *) { let request = NSURLRequest.init(url: URL.init(string: urlStr)!

  • iOS中WKWebView白屏问题的分析与解决

    前言 随着WKWebView的推出, 解决了很多UIWebView 的问题.比如加载速度慢,内存泄露等问题.WKWebView是在iOS 8 推出,前段时间正好把项目也适配到iOS 8 以上了,终于可以把项目中的UIWebView 替换成WKWebView. WKWebView的特点: 性能高,稳定性好,占用的内存比较小, 支持JS交互 支持HTML5 新特性 可以添加进度条(然并卵,不好用,还是习惯第三方的). 支持内建手势, 据说高达60fps的刷新频率(不卡) 但是发现在使用的时候还是有很

随机推荐