- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章iOS和JS交互教程之WKWebView-协议拦截详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前言 。
由于xcode8发布之后,编译器开始不支持ios 7了,这样我们的app也改为最低支持ios 8.0,既然需要与web交互,那自然也就选择使用了 ios 8.0之后 才推出的新控件 wkwebview. 。
相比与 uiwebview, wkwebview 存在很多优势:
先解释下标题:“ios与js交互”。ios指ios原生代码(文章只有oc示例),js指web前端(不单指javascript),交互指js调用ios和ios调用js.
本文介绍通过 wkwebview协议拦截的方式实现ios与js交互.
wkwebview是apple在ios8推出的webkit框架中的负责网页的渲染与展示的类,相比uiwebview速度更快,占用内存更少,支持更多的html特性.
1、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,不然会崩溃.
2、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 。
最后此篇关于iOS和JS交互教程之WKWebView-协议拦截详解的文章就讲到这里了,如果你想了解更多关于iOS和JS交互教程之WKWebView-协议拦截详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
internal protocol Reducer { associatedtype S : BaseState associatedtype A : BaseActi
我在考虑我的应用程序中的验证检查,我认为在任何模型上调用 ValidatorFactory,实现 Validee,这意味着说哪个类负责 ValidatorCreation 听起来不错。但是下面的代码不
我已经定义了 2 个协议(protocol)。我需要第一个 (NameProtocol) 来执行 Equatable 协议(protocol)。而另一个类 (BuilderProtocol) 有一个返
在上传方面,WebDAV 协议(protocol)在哪些方面优于 HTTP 协议(protocol)。 Socket Upload 协议(protocol)和 WebDav Upload 协议(pro
是否可以在任何版本的 Swift 中扩展具有混合类/协议(protocol)类型约束的协议(protocol)?例如,仅当 Self 是 UIViewController 的子类并且符合 Protoc
我有一个协议(protocol) (ProtocolA),其中包含符合第二个协议(protocol) (ProtocolB) 的单个属性。 public protocol ProtocolA {
NSObject 协议(protocol)带有常用的协议(protocol)模板,但它似乎并不是协议(protocol)实际实现所必需的。将其排除在外似乎完全没有任何改变。那么,协议(protocol
我想根据这两种协议(protocol)的一般特征(例如开销(数据包)、安全性、信息建模和可靠性)来比较 OPC UA 和 MQTT。我在哪里可以找到每个协议(protocol)的开销和其他特性的一些示
使用 Swift 4,我正在尝试编写一个自定义协议(protocol),它提供对 @objc 协议(protocol)的一致性。 一些代码 更具体地说,我有一个自定义协议(protocol) Sear
我想定义一个在 Viper 架构中使用的协议(protocol),以使用具有弱属性的协议(protocol)在 Viper 组件之间建立连接,但我收到以下错误消息: 'weak' may only b
我在同一个网络中有 3 个 docker 容器: 存储 (golang) - 它提供了用于上传视频文件的 API。 主播 (nginx) - 它流式传输上传的文件 反向代理 (姑且称之为代理) 我有
我打算在我的项目中使用 php socket。它需要用户登录才能根据 session 填充内容。所以我的问题是,TCP/IP 协议(protocol)也像 HTTP 协议(protocol)一样为每个
目前,我的网站有两个版本。一种带有 https://-证书,一种没有。我想将我网站的 http 版本上的所有用户 301 重定向到我网站的 https://版本。 这似乎不可能,因为创建重定向将导致重
目前,我的网站有两个版本。一种带有 https://-证书,一种没有。我想将我网站的 http 版本上的所有用户 301 重定向到我网站的 https://版本。 这似乎不可能,因为创建重定向将导致重
我有一个 Swift View Controller ,它定义了一个在 Objective-C View Controller 中应该遵循的协议(protocol): ChildViewControl
我在客户那里有数百个硬件设备,需要通过telnet接口(interface)发送HTTP数据。 目标是等待数据的 Apache 2 Web 服务器和 PHP 脚本。 这已经可以正常工作了,但是我们发现
我发现如果我创建一个这样的协议(protocol): protocol MyProtocol { } 我不能这样做: weak var myVar: MyProtocol? 我找到了解决这个问题的方法
Xcode 基于模板生成了这个头文件: // this file is XYZAppDelegate.h #import @interface XYZAppDelegate : UIRespond
我在 github 中有一个公开的存储库,我正在开发一个开源应用程序,用于制作产品目录和小型 cms 内容。 我还有一个私有(private)仓库(不托管在github),它是在托管在github的开
您好,我想让别人看到私有(private) repo 代码,但不想公开我的 repo ,也不希望他们有能力更改内容。这可能吗?我查看了网站的“管理”部分,但没有找到合适的内容。谢谢大家。 最佳答案 据
我是一名优秀的程序员,十分优秀!