iOS关于UIWebView和Javascript相互调用及WebViewJavascriptBridge分析

8 篇文章 0 订阅
1 篇文章 0 订阅

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传值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值