对于JS与OC交互的再次理解(强烈呼吁摒弃百度搜索,推荐google、必应)

文字较多,耐心读一下,肯定有所收益!

*开发中经常使用WebViewJavascripBridge进行H5与原生的交互,也知道OC用代理拦截H5的url做出一些操作,OC可以注入JS代码改变H5的样式什么的,但一直困惑的我的是:

  • 他们是怎么把我OC端的一个NSDictionary、NSArray、NSString的数据发给H5端的,又怎么把H5端的数据发给我的呢 ????????????
  • 最后明白了【数据通道】 :
  • webview注入js代码的API:evaluateJavaScript: completionHandler:^(id _Nullable result, NSError * _Nullable error){ }

两端 数据传递 通道

 //1. OC端需要注入【可执行的JS代码】的字符串: @"fuction('data')",OC端的可以将数据以JS方法fuction的参数 data 传入,在fuction中将数据data取出以供HTML端使用。
 [webView evaluateJavaScript:@"fuction('data')" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
    //2. result 是执行完JS代码后返回的结果,HTML端的数据可以通过result返回到OC端以供使用,即执行fuction方法后,return一个数据交给OC端。
    //3. error 是执行完JS代码时遇到的error,可忽略。
  }];

两端的数据传递具体过程

总结性的讲:

  1. OC端发数据是组装好数据直接发;
  2. HTML端发数据是组装好数据,通知OC端自己过来取数据。
  • OC端发送数据:
    1. 准备数据:创建一个字典,以key-Value的形式组装成一个data,然后将data序列化成一个转义后的json字符串;
    2. 利用注入JS代码通道:[webView evaluateJavaScript:@"sendData('data')" completionHandler:^(id _Nullable result, NSError * _Nullable error) { }];
    直接将data送入JS代码中,并在sendData方法中将data取出,以供HTML页面使用处理逻辑什么的。
  • JS端发送数据:
    1. 准备数据:js创建一个对象,以key-value的形式组装一个data,然后将data序列化成json字符串;
    2. 利用一个<i>标签,重设一下改标签的src(该src是两端约定好的),发起一个请求;
    3. OC端通过WebView的代理方法拦截到了url,判断一下url是否是之前约定好的HTML发送数据的url,如果是则组织一段JS代码字符串: @"getData()";
    4. OC端利用注入JS代码通道:[webView evaluateJavaScript:@"getData()" completionHandler:^(id _Nullable result, NSError * _Nullable error) { // result :HTML端返回的数据 }];
    JS代码中执行getData()方法,在该方法中JS将组装好的data,return出来。
    5. 然后 OC 端再从Block中获取到HTML端发送的数据data,从data中取出数据处理相关逻辑。
知道了JS与OC之间的数据传输通道,以及传输的具体过程后,我们再看这个框架。发现两端创建的bridge,其实就是在为这个数据传输通道做辅助工作,比如js端定义了两个方法:function _fetchQueue()、function _handleMessageFromObjC( data ),前一个方法是OC获取JS端数据时注入js代码字符串执行该方法,该方法将js端的数据return出来;后一个方法是OC将数据传送JS端时,将OC端数据作为该方法的参数,注入js代码字符串执行该方法,完成了将数据传给JS操作。因此可见,bridge就是为这条数据通道做辅助工作的。
就是因为没搞明白这条结论,才导致网络上介绍WebViewJavascripBridge框架的文章,将重点放在bridge上讲,讲bridge是如何如何执行这个方法,那个方法,把代码流程讲了一遍,看似讲明白了,但真的是隔靴搔痒,未讲到核心点。一开始我也是这样,惭愧!
  • 有了以上的认识之后,我们再看bridge。我们都知道两端都一个bridge,刚才也说了bridge就是为数据通道服务的,那么bridge都能帮数据通道做什么呢?有通过哪些东西辅助呢?
    只要介绍bridge提供的辅助工具就能全部理解了:
    一个属性、 两张表、 四个方法。

*一个属性:sendMessageQueue,是一个数组类型,用于存储该端组装的Message,即Message的集合。这里的Message就是一个一个的数据包,是key-Vlaue的对象。为什么是用数组呢?个人认为保证数据传递顺序。

*两张表:方法表:保存的是该端对外注册的方法以供一端发送消息调用,以key-value的形式保存,比如:“买苹果”:{ 买苹果的具体操作函数 }。
回调表:保存的是发送消息让另一端执行后的回调,也是以key-value的形式保存,其key是按照一定规则创建保证其唯一性,比如:"买手表的回调":{把表买回来之后的操作函数}

  • 四个方法:1. 注册方法:两端约定一个key,将key对应执行的方法保存到表。
    2 . 发消息方法:使用约定好的key,在带上数据data,发送消息让另一端执行相关操作,如果需要执行完成后给出回调,则在发送消息时也把回调处理的block带上,那这个block会存在回调表。
    3 . 组装数据方法:将发送消息方法中提供的key、data、block的key组装成功一个Message,并转成json字符串,以供发送给另一端使用。
    4 . 解析数据方法:将另一端发送到数据,从json字符串转成一个key-value对象,根据key,从方法表中找到方法,并将data最为该方法的参数,然后执行该方法,执行完成后,如果从message中能获取到block的key,则将block的key和执行后的结果数据,在发送消息给另一端,另一端获取到消息后,从回调表中根据key找到block,然后将回到来的数据作为block参数,执行回调block。

例子:OC端让H5端买手表

1. H5端在事件表注册事件:“买手表” :{...}
2. OC端在回调表中保存买表的回调:"callbackID" : {买表后的回调}
3. OC端创建了一个Message:{handleName:"买手表", data : "1000元", responseCallback : "callbackID"},保存在sendMessageQueue中
4. OC端通过【组装数据方法】将message从sendMessageQueue中取出转成了一个json字符串,并将该数据以参数的形式放入拼接的JS代码字符串中,这段JS代码就是执行JS端【解析数据方法】
5. OC端通过数据通道将数据传入JS端
6. JS端执行【解析数据方法】,在方法中将参数,从json字符串转成key-value对象,得到handleNmae、data、callBackID。首先根据handleNmae从注册表中找到买表的函数,然后将data中的【1000元】作为参数执行买手表的{...买手表去喽...}
7. JS端买完手表后,需要将手表返回给OC端,这时JS端将callbackID和表组成了一个Message:{responsID:"callbackID" , data : 表 },保存到sendMessage中
8. JS端通过一个i标签,改变src发起一个请求,通知OC端过来拿数据
9. OC端拦截到url,得知要他去取数据,则组织了一段JS代码,通过数据通道将数据拿回来,即调用JS端的【组装数据方法】将从sendMessageQueue中拿到Message返回到OC端
10. OC端拿到数据后,获取callbackID,并根据它从回调表中找到回调的block,取出data:表,将表作为block的参数执行block。这时OC已经拿到了他的表了,到此结束。


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容