理解WebViewJavaScriptBridge原理

OC可以调用js,但是js不能直接调用oc. 必须通过截取url来

前提条件都是需要bridge在OC实例化,然后二者的互调才可以进行下去

_bridge= [WebViewJavascriptBridge bridgeForWebView:webView];

实例化的原理是:JSBridge里面有UIWebview和JSBridgeBase的实例,然后分别成为二者的代理,负责协调双方的工作

第一部分:js调用OC方法:

由OC注册,JS主动触发(调用callhandler方法)

1.执行前提条件

2.OC在注册(registerHandler)的时候,OC会注册一个回调函数

[_bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback)

,该回调函数包括一个注册事件和一个回调方法,JSB中的base实例会把该注册事件放进到base的一个消息池子(负责接受多个OC注册事件)中,方便后续处理

3.网页加载出来后整个oc的执行流程

相当于JS的注册绑定方法--->当UIWebview把该网页加载出来的时候,在该html文件中会通过JS的iframe元素执行JS和OC端的绑定。

该方法是由于webview的delegate设置为了JSB,所以会在JSB中触发其代理方法:shouldStartLoadWithRequest,然后在该方法中进行如下操作:

根据url(此时的url是由上述的iframe元素带进来的,类似:wvjbscheme://BRIDGE_LOADED) ,来决定此时是走registerHandler 还是 callHandler方法,此时是register方法,那么则执行JSBridgeBase的injectJavascriptFile方法(正如函数名一样,此时执行在工程里面放置的JS文件(在我们的工程里面由于要兼容JSBridge的历史版本,所以这里是在webViewDidFinishLoad里面直接调用injectJavascriptFile方法)),这个文件的主要作用就是向OC发消息来定义一些常量,注册一些实例,定义一些回调方法,方便在OC的逻辑中进行处理和跟踪,文件执行完毕后,接下来就会查找在base中时候有OC要发送给JS的回调信息,没有则执行结束(这里显然没有)

4.oc和js相互绑定过后,此时由JS触发OC函数

点击JS上的button会触发callHandler,会触发代理shouldStartLoadWithRequest:

此时由于经由上述的JS文件执行的时候会执行一个叫做window.WebViewJavascriptBridge的注册

window.WebViewJavascriptBridge = {registerHandler:registerHandler,callHandler:callHandler,disableJavscriptAlertBoxSafetyTimeout:disableJavscriptAlertBoxSafetyTimeout,_fetchQueue:_fetchQueue,_handleMessageFromObjC:_handleMessageFromObjC    };

由于js主动触发了callHandler,url所以变成了

wvjbscheme://WVJB_QUEUE_MESSAGE,所以此时会走一个执行js函数的方法(猜测是通过上述js文件的作用从而能够解析出JS传递过来的信息)来从网页上获得网页的传递过来的信息!

{  "callbackId" :"cb_2_1468844907930",  "handlerName" :"testObjcCallback",  "data" : {    "foo" :"bar"}}

然后进入base的flushMessageQueue:函数,在里面通过解析该dict,从而获得注册事件名handlerName,然后获得该事件的回调,并调用那个事件的回调block

handler(message[@"data"], responseCallback);

至此,整个JS回调OC过程完成,达到了JS给OC发送数据的目的,同时如果OC想要给JS发送消息,只需把信息放进responseCallback就会回调给JS(方法就是第二部分的内容),以达到互相通信的目的

第二部分:OC调用js方法:

由js注册,OC主动触发(调用callhandler方法)

1.执行前提条件

2.网页加载出来后整个oc的执行流程

相当于JS的注册方法--->当UIWebview把该网页加载出来的时候,在该html文件中会通过JS的iframe元素执行JS和OC端的绑定。

该方法的由于webview的delegate设置为了JSb,所以会在JSB中触发其代理方法:shouldStartLoadWithRequest,然后在该方法中进行如下操作:

根据url(此时的url是由上述的iframe元素带进来的,类似:wvjbscheme://BRIDGE_LOADED) ,来决定此时是走registerHandler 还是 callHandler方法,此时是register方法,那么则执行JSBridgeBase的injectJavascriptFile方法(正如函数名一样,此时执行在工程里面放置的JS文件),这个文件的主要作用就是向OC发消息来定义一些常量,注册一些实例,定义一些回调方法,方便在OC的逻辑中进行处理和跟踪,

其中会执行一个叫做window.WebViewJavascriptBridge的注册

window.WebViewJavascriptBridge = {registerHandler:registerHandler,callHandler:callHandler,disableJavscriptAlertBoxSafetyTimeout:disableJavscriptAlertBoxSafetyTimeout,_fetchQueue:_fetchQueue,_handleMessageFromObjC:_handleMessageFromObjC    };

由于js函数中一进来便主动触发了registerHandler,所以url变成了

wvjbscheme://WVJB_QUEUE_MESSAGE

文件执行完毕后,会在JSB中执行

elseif([_baseisQueueMessageURL:url]) {NSString *messageQueueString = [self_evaluateJavascript:[_base webViewJavascriptFetchQueyCommand]];            [_baseflushMessageQueue:messageQueueString];            }

恰好此时url 满足情况,则进入消息分发流程,但是由于此时messageQueueString什么也没有,所以直接跳出

3.OC和js相互绑定过后,此时由OC函数触发JS

点击OC的button,触发OC函数

[_bridge callHandler:@"testJavascriptHandler"data:@{@"name": @"wayne"} responseCallback:^(idresponseData)

调用Base的

- (void)sendData:(id)dataresponseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName

使用dictionary进行消息拼接,形如:

{    callbackId ="objc_cb_1";//定义OC的回调iddata =    {        name = wayne;    };//OC传递给JS的数据handlerName = testJavascriptHandler;//为了区分是哪一个注册事件,以便后续的消息分发}

封装完成过后,会调用[self _dispatchMessage:message]来进行消息分发,消息分发是在主线程里面执行的,消息的内容经过再次封装过后形似:

WebViewJavascriptBridge._handleMessageFromObjC('{\"callbackId\":\"objc_cb_1\",\"data\":{\"name\":\"wayne\"},\"handlerName\":\"testJavascriptHandler\"}');

**WebViewJavascriptBridge._handleMessageFromObjC**-->查看JS文件可知,这个文件是给JS使用的,会执行_handleMessageFromObjC的方法把消息分发给JS中的registerHandler中的方法体,OC回调过程结束!!

4.JS传递数据给OC

但是此时在执行JS中的代码的时候发现有回调block,则会执行改block

然后会再次执行UIWebview的代理方法:shouldStartLoadWithRequest函数,此时url已经是

wvjbscheme://WVJB_QUEUE_MESSAGE

文件执行完毕后,会在JSB中执行

elseif([_baseisQueueMessageURL:url]) {        NSString *messageQueueString = [self_evaluateJavascript:[_base webViewJavascriptFetchQueyCommand]];        [_baseflushMessageQueue:messageQueueString];      }

messageQueueString由第一部分知识可知:是JS传递过来的数据:

[{"handlerName":"testJavascriptHandler","responseId":"objc_cb_1","responseData":        {"Javascript Says":"Right back atcha!==>test"}}]

执行flushMessageQueue函数:并在里面执行block函数体,获得JS传递过来的数据

至此,互相传递数据过程完毕!


原文连接:http://www.cnblogs.com/WayneLiu/p/5738936.html

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

推荐阅读更多精彩内容