iOS关于UIWebView和Javascript相互调用及WebViewJavascriptBridge分析
iOS中 JS与OC通信
1, 基本原理。
iOS中展示html文档的控件为UIWebView和WKWebView,都可以直接执行js代码;但是JS不能直接执行OC的代码,好在UIWebView和WKWebView的代理方法可以拦截html中的url请求,所以就可以利用这一点实现JS到OC的通信。因此在html中在需要向OC通信的地方发起一次特殊的url请求就可以了,在html中发起url请求可以用document.location和一个隐藏的iframe的src实现,建议用后者,因为前者在连续请求的时候会丢失前一次的请求。
2,JS与OC通信的简单实现。
如果JS与OC只是要求简单的通信可以直接把需要传递的参数拼接在url后边,在webView拦截到请求后从中解析出参数,然后就可以做相应的处理了。
这个简单的实现功能不够大,如果在相互传递的参数是json等数据量较大的情况下就不方便了,而且,相互通信时没有回调,没法将相互处理后的结果带回。
3,JS与OC通信桥封装实现。
JS与OC简单实现使用范围有限。如果需要把处理结果带回或者传递的数据量较大时就满足不了。所以引入‘通信桥’的概念,为了传递大量数据就要把参数从url里面摘出来,为了能带回处理结果,就要有存储回调的数据结构,通信桥就完成了这些处理。通信桥包含js处理代码和oc代码处理两部分,各自都有两个集合,一个存储消息处理代码块,一个存储回调处理代码块。
另外js部分,还需要一个集合存消息体,这个集合称它为消息队列,消息体即包含参数,OC操作名(方法名),和回调id(避免重复,所以拼上用时间毫秒数)。
消息体结构为{
“data”:{},
“callBackId”:””
“handerName”:””
“responseId”:””
}
data为传递的参数,callBackId是回调处理标示,handerName是调用js或oc代码的操作名(方法名),responseId是回调id,如果消息体存在responseId,就是‘回调消息体’,如果不存在就是‘调用消息体’。
当JS向OC通信时,先创建消息体,然后把消息加入消息队列,最后设置ifame的src,触发webView的代理方法,webView拦截到url后直接调用js代码获取消息桥中js的消息队列,然后循环消息队列处理消息,回调结果(也是发一次url请求)。
当OC向JS通信时,也生成一个消息体,里面包含传递的参数,JS操作的代码块名称(方法名),和回调id。调用消息桥JS里的处理消息方法,把消息转成json字符串作为参数传递到JS端。消息桥JS消息处理完成后,回调结果(也是调用消息桥JS方法 )。
OC端处理JS的消息。调用JS的_OcfetchQueue方法,获取消息队列,循环依次处理。如果消息中存在responseId,说明这个消息是OC调用JS方法的回调结果,于是根据responseId从回调处理集合(responseCallbacks)中取出回调处理block代码执行;如果消息中不存在responseId说明是JS发送的调用OC操作(方法)的消息,于是根据handerName从已注册的操作集合(messageHandlers)中取出对应的消息处理block执行,并且把callBackId作为responseId和处理结果data产生一个回调消息体,格式化成json字符串。在处理完成后调用js的_OcHandleMessageFromObjC方法,把回调消息体json字符串作为该方法的参数带回到JS中。
JS端OC的消息。JS的_OcHandleMessageFromObjC方法被调用时,参数就是OC发送的消息json字符串。如果消息中responseId存在,说明该消息是JS调用OC操作(方法)的回调消息,根据responseId从从回调处理集合(responseCallbacks) 中取出回调处理代码块,调用该回调处理的js代码块;如果
消息中不存在 responseId就是OC发送的调用JS操作(方法)的消息,于是根据handerName从已注册的操作集合(messageHandlers)中中取出并执行对应的消息处理的js代码块,并且把callBackId作为responseId和处理结果data产生一个回调消息体,把消息放入消息队列(sendMessageQueue)中,然后设置iframe.src,触发webView的代理方法,通知OC去处理回调结果。
4,不用webView的代理拦截方式实现,直接用系统coreJavaScript提供的方法实现。
通过JSContext实现JS与OC的通信。
先从webView中获取JSContext实例。
JSContext *context=[self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
然后给JS中要调用的方法绑定一个block代码块:
context[@"bookImageClicked"] = ^(NSString * bookInfoJson){
NSLog(@"bookInfoJson...>:%@",bookInfoJson);
NSArray * array = @[@"阿斯顿飞",@"对方告诉对方",@"大范甘迪"];
NSDictionary * dict = @{@"key1":@"asdf",@"key2":@"大师傅"};
return dict;
};
这样在页面里就可以调用bookImageClicked这个方法了。如此就实现了JS调用OC方法,及OC向JS传值。
iOS关于UIWebView和Javascript相互调用及WebViewJavascriptBridge分析相关推荐
- android调用js函数方法,Android和JavaScript相互调用的方法
本文实例讲述了Android和JavaScript相互调用的方法.分享给大家供大家参考,具体如下: Html页面和Java代码结合的方式一般用在界面经常被更改 的情况下,可以讲html放在网络中,软件 ...
- iOS原生和H5的相互调用
为什么现在越来越多的APP中开始出现H5页面? 1,H5页面开发效率更高,更改更加方便: 2,适当缩小APP安装包的大小: 3,蹭热点更加方便,比如五一,十一,双十一搞活动: 那么为什么说H5无法取代 ...
- Android 与 JavaScript 相互调用桥梁 JSBridge
JSBridge 什么是JSBridge JSBridge:听其取名就是js和Native之前的桥梁,而实际上JSBridge确实是JS和Native之前的一种通信方式.简单的说,JSBridge就是 ...
- Unity与iOS原生代码之间的相互调用
1.Unity调用iOS: 1.1.在Unity C#中: [ DllImport( "__Internal" )] private static extern int _show ...
- Pycharm下同一目录的py文件不能相互调用的原因分析
1.首先确保所在目录是Python Package而不是一般的New Stratch File Python Package下有__init___.py或自己建空的__init___.py 2.pyc ...
- 各编程语言 + aardio 相互调用示例(简易代码)
代码都很简单,复制可直接运行.aardio 快速调用 C,C++,C#,Java,R,V,Python,JavaScript,Node.js,Rust,PHP,Ruby,PowerShell,Fort ...
- 各编程语言相互调用示例,代码简单,生成的软件体积也很小
aardio 支持混入很多不同的编程语言,代码简单,生成的软件体积也很小.下面看示例. aardio 直接调用系统 API 函数( 支持回调.相互调用 ): var ret,point = ::Use ...
- 转载 iOS js oc相互调用(JavaScriptCore) --iOS调用js
iOS js oc相互调用(JavaScriptCore) 从iOS7开始 苹果公布了JavaScriptCore.framework 它使得JS与OC的交互更加方便了. 下面我们就简单了解一下这个框 ...
- iOS下JS与OC互相调用(一)--UIWebView 拦截URL
1.在JS 中做一次URL跳转,然后在OC中拦截跳转.(这里分为UIWebView 和 WKWebView两种,去年因为还要兼容iOS 6,所以没办法只能采用UIWebView来做.) 2.利用WKW ...
最新文章
- 使用浏览器wpf应用程序时访问数据库需要报权限错误的解决方法
- linux(centos)下mysql忘记root密码
- 滴滴Uber合并?光大是不行的
- 双缓冲法解决重绘和闪屏问题
- xpath contains_Python神技能 | 六张表,搞定 Xpath 语法!
- Maskros的蓝桥刷题之路(1-13)
- shiro学习(1):shiro简介
- 论文学习8-How Question Generation Can Help Question Answering over Knowledge Base(KBQA-知识问答)
- 如何 方法内指令重排 进制_谈谈指令重排
- truncate delete 与 drop的区别
- PowerPoint笔记(四)
- Matlab Tricks( 八)—— 将 pgm 格式文件转换为 png 格式
- 黑群晖 linux 修改参数,黑群晖 DS918+ 修改引导参数隐藏引导盘和数据盘
- 整人程序源码(VB)
- 计算机sci论文怎么写,计算机学院陈端兵教授分享SCI论文写作方法
- uni-app(登录页面)
- pscc2021绿色免安装完整版
- 什么是现场服务管理系统(FSM)?有什么好处?
- 手机收到回复TD退订的短信,需要回复吗?今天算是搞明白了
- 3dmax 焊接顶点死活焊接不上的爬坑日记。
热门文章
- 【Software-vscode】用vscode调试ruby 和 ruby for Sketchup
- 广州某某某某科技前端开发面试
- UML 状态图 statechart diagram
- 腾讯云学生服务器可以用来做什么?
- 信号频谱、幅度、功率和能量
- bandicom录屏音画不同步_屏幕录制的视频画面和声音不同步的问题 - Bandicam(班迪录屏)...
- 看看VintaSoftTwain.NET SDK最新版
- 分表分库Redis集群ES集群
- SAPLPD已停止工作
- DPtech ADX-3000GA负载均衡机业务配置