解决方案:
1.URL Scheme
2.JsBridge
一.URL scheme
URL Scheme是UIWeview为Web端提供的唯一一个向Native传递消息的通路,早期利用该机制实现了比如点击网页上的一个链接跳转到个人页的功能。
下面是使用该技术要做的工作:
1.约定一个自定义Scheme的URL比如kimliang://openperson?pid=
2. Native在实现webView:shouldStartLoadWithRequest:navigationType:代理,通过拦截每次跳转,判断是不是约定好的URL,如果是则执行自定义行为
这种方式的缺点:
1.一开始的时候没有形成一个约定URL的规则,导致很多随意发挥的URL
2.每次有新的自定义URL行为都要在webView:shouldStartLoadWithRequest:navigationType:代理里面增加代码,不利于维护
3.这种方式Web端无法获取Native的执行反馈
二.JSBridge开发指南
JsBridge的设计就是要克服上面列举的URL Scheme的缺点。Jsbridge的设计遵循以下原则:
1.方便Web端开发人员调用,使用URL Scheme这种方式Web端开发人员需要自己去组装URL,这个工作可以由Jsbridge来完成。
2.作为一个组件提供
3. Web端在需要的情况下可以获得执行反馈
方便的调用方式:
Jsbridge在Web端提供了两种调用Native功能的方法:
jsbridge.invoke('function_name', param,success_cb, error_cb)
jsbridge.call('function_name', param)
为什么分两种调用方式在会在下面说明。这种方式就跟方法调用类似,只不过方法名也需要当做参数传递。在内部JsBridge会将参数打包成特定格式的URL。
作为组件提供:
webView:shouldStartLoadWithRequest:navigationType:代理是唯一的获取Web端传递的信息的途径,JsBridge也只能依赖实现该代理。为了不与使用JsBridge的代码耦合,JsBridge使用了一个比较hack的方法,当将JsBridge实例与UIWebview连接的时候JsBridge会替换原来UIWebview的webView:shouldStartLoadWithRequest:navigationType:代理,当发现是JsBridge内部的URL则会执行相应的JsBridge功能,如果不是则调用原来的代理方法来处理。
给Web端反馈:
上面说到JsBridge的Web端提供了invoke和call两种调用方式,其中invoke比call调用方式多了两个参数,这两个参数是用来获取返回值的回调,如果Native调用成功,则success_cb会被调用,注意这里的调用成功是指Native执行了function_name指定的方法,至于方法执行的结果还要跟据success_cb的参数来决定,当Native没有function_name指定的方法或者其他JsBridge内部错误会调用error_cb。
当jsbridge.invoke('function_name',
param, success_cb, error_cb)调用的时候,JsBridge的Web端会为该次调用分配一个唯一的CallID,使用该CallID为key,success_cb和error_cb会被记录到一张表中。该CallID会跟function_name和param一同打包传递给Native。Native执行完相应功能后,调用stringByEvaluatingJavaScriptFromString:方法将CallID和返回结果返回到Web端,Web端通过CallID找到相应的success_cb或者error_cb执行。
JS端会维护一个队列存放函数调用,用于回调处理,同理Native端也会维护一个队列,用于存放调用js方法回调处理。
参考文章:
使用WebViewJavascriptBridge实现OC与JS交互:http://www.jianshu.com/p/ca496cb680fe