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分析相关推荐

  1. android调用js函数方法,Android和JavaScript相互调用的方法

    本文实例讲述了Android和JavaScript相互调用的方法.分享给大家供大家参考,具体如下: Html页面和Java代码结合的方式一般用在界面经常被更改 的情况下,可以讲html放在网络中,软件 ...

  2. iOS原生和H5的相互调用

    为什么现在越来越多的APP中开始出现H5页面? 1,H5页面开发效率更高,更改更加方便: 2,适当缩小APP安装包的大小: 3,蹭热点更加方便,比如五一,十一,双十一搞活动: 那么为什么说H5无法取代 ...

  3. Android 与 JavaScript 相互调用桥梁 JSBridge

    JSBridge 什么是JSBridge JSBridge:听其取名就是js和Native之前的桥梁,而实际上JSBridge确实是JS和Native之前的一种通信方式.简单的说,JSBridge就是 ...

  4. Unity与iOS原生代码之间的相互调用

    1.Unity调用iOS: 1.1.在Unity C#中: [ DllImport( "__Internal" )] private static extern int _show ...

  5. Pycharm下同一目录的py文件不能相互调用的原因分析

    1.首先确保所在目录是Python Package而不是一般的New Stratch File Python Package下有__init___.py或自己建空的__init___.py 2.pyc ...

  6. 各编程语言 + aardio 相互调用示例(简易代码)

    代码都很简单,复制可直接运行.aardio 快速调用 C,C++,C#,Java,R,V,Python,JavaScript,Node.js,Rust,PHP,Ruby,PowerShell,Fort ...

  7. 各编程语言相互调用示例,代码简单,生成的软件体积也很小

    aardio 支持混入很多不同的编程语言,代码简单,生成的软件体积也很小.下面看示例. aardio 直接调用系统 API 函数( 支持回调.相互调用 ): var ret,point = ::Use ...

  8. 转载 iOS js oc相互调用(JavaScriptCore) --iOS调用js

    iOS js oc相互调用(JavaScriptCore) 从iOS7开始 苹果公布了JavaScriptCore.framework 它使得JS与OC的交互更加方便了. 下面我们就简单了解一下这个框 ...

  9. iOS下JS与OC互相调用(一)--UIWebView 拦截URL

    1.在JS 中做一次URL跳转,然后在OC中拦截跳转.(这里分为UIWebView 和 WKWebView两种,去年因为还要兼容iOS 6,所以没办法只能采用UIWebView来做.) 2.利用WKW ...

最新文章

  1. 使用浏览器wpf应用程序时访问数据库需要报权限错误的解决方法
  2. linux(centos)下mysql忘记root密码
  3. 滴滴Uber合并?光大是不行的
  4. 双缓冲法解决重绘和闪屏问题
  5. xpath contains_Python神技能 | 六张表,搞定 Xpath 语法!
  6. Maskros的蓝桥刷题之路(1-13)
  7. shiro学习(1):shiro简介
  8. 论文学习8-How Question Generation Can Help Question Answering over Knowledge Base(KBQA-知识问答)
  9. 如何 方法内指令重排 进制_谈谈指令重排
  10. truncate delete 与 drop的区别
  11. PowerPoint笔记(四)
  12. Matlab Tricks( 八)—— 将 pgm 格式文件转换为 png 格式
  13. 黑群晖 linux 修改参数,黑群晖 DS918+ 修改引导参数隐藏引导盘和数据盘
  14. 整人程序源码(VB)
  15. 计算机sci论文怎么写,计算机学院陈端兵教授分享SCI论文写作方法
  16. uni-app(登录页面)
  17. pscc2021绿色免安装完整版
  18. 什么是现场服务管理系统(FSM)?有什么好处?
  19. 手机收到回复TD退订的短信,需要回复吗?今天算是搞明白了
  20. 3dmax 焊接顶点死活焊接不上的爬坑日记。

热门文章

  1. 【Software-vscode】用vscode调试ruby 和 ruby for Sketchup
  2. 广州某某某某科技前端开发面试
  3. UML 状态图 statechart diagram
  4. 腾讯云学生服务器可以用来做什么?
  5. 信号频谱、幅度、功率和能量
  6. bandicom录屏音画不同步_屏幕录制的视频画面和声音不同步的问题 - Bandicam(班迪录屏)...
  7. 看看VintaSoftTwain.NET SDK最新版
  8. 分表分库Redis集群ES集群
  9. SAPLPD已停止工作
  10. DPtech ADX-3000GA负载均衡机业务配置