三端易用的现代跨平台JavaScript Bridge之 IOS篇

2,635 阅读5分钟

dsBridge是一个三端(Android、IOS、JavaScript)易用的现代跨平台 JavaScript bridge, 通过它,你可以在Javascript和原生之间同步或异步的调用彼此的函数.

Github: github.com/wendux/DSBr…

特性

  1. Android、IOS、Javascript 三端易用,轻量且强大、安全且健壮。
  2. 同时支持同步调用和异步调用
  3. 支持以类的方式集中统一管理API
  4. 支持API命名空间
  5. 支持调试模式
  6. 支持API存在性检测
  7. 支持进度回调:一次调用,多次返回
  8. 支持Javascript关闭页面事件回调
  9. 支持Javascript 模态/非模态对话框
  10. Android端支持腾讯X5内核

安装

pod "dsBridge"

示例

请参考工程目录下的 dsbridgedemo/ 文件夹. 运行并查看示例交互.

如果要在你自己的项目中使用 dsBridge :

使用

  1. 新建一个类,实现API

    @implementation JsApiTest
    //同步API 
    - (NSString *) testSyn:(NSString *) msg
    {
        return [msg stringByAppendingString:@"[ syn call]"];
    }
    //异步API
    - (void) testAsyn:(NSString *) msg :(void (^)(NSString * _Nullable result,BOOL complete))completionHandler
    {
        completionHandler([msg stringByAppendingString:@" [ asyn call]"],YES);
    }
    @end 
    

    可以看到,DSBridge正式通过API类的方式集中、统一地管理API。

  2. 添加API类实例到 DWKWebView

    DWKWebView * dwebview=[[DWKWebView alloc] initWithFrame:bounds];
    // register api object without namespace
    [dwebview addJavascriptObject:[[JsApiTest alloc] init] namespace:nil];
    
  3. 在Javascript中调用原生 (Java/Object-c/swift) API ,并注册一个 javascript API供原生调用.

    • 初始化 dsBridge

      //cdn方式引入初始化代码(中国地区慢,建议下载到本地工程)
      //<script src="https://unpkg.com/dsbridge@3.0.7/dist/dsbridge.js"> </script>
      //npm方式安装初始化代码
      //npm install dsbridge@3.0.7
      var dsBridge=require("dsbridge")
      
    • 调用原生API ,并注册一个 javascript API供原生调用.

      
      //同步调用
      var str=dsBridge.call("testSyn","testSyn");
      
      //异步调用
      dsBridge.call("testAsyn","testAsyn", function (v) {
        alert(v);
      })
      
      //注册 javascript API 
       dsBridge.register('addValue',function(l,r){
           return l+r;
       })
      
  4. 在Object-c中调用Javascript API

       [dwebview callHandler:@"addValue" arguments:@[@3,@4] completionHandler:^(NSNumber* value){
              NSLog(@"%@",value);
       }];
    

命名空间

命名空间可以帮助你更好的管理API,这在API数量多的时候非常实用,比如在混合应用中。DSBridge (>= v3.0.0) 支持你通过命名空间将API分类管理,并且命名空间支持多级的,不同级之间只需用'.' 分隔即可。

调试模式

在调试模式时,发生一些错误时,将会以弹窗形式提示,并且原生API如果触发异常将不会被自动捕获,因为在调试阶段应该将问题暴露出来。如果调试模式关闭,错误将不会弹窗,并且会自动捕获API触发的异常,防止crash。强烈建议在开发阶段开启调试模式,可以通过如下代码开启调试模式:

// open debug mode
[dwebview setDebugMode:true];

进度回调

通常情况下,调用一个方法结束后会返回一个结果,是一一对应的。但是有时会遇到一次调用需要多次返回的场景,比如在javascript钟调用端上的一个下载文件功能,端上在下载过程中会多次通知javascript进度, 然后javascript将进度信息展示在h5页面上,这是一个典型的一次调用,多次返回的场景,如果使用其它Javascript bridge, 你将会发现要实现这个功能会比较麻烦,而DSBridge本省支持进度回调,你可以非常简单方便的实现一次调用需要多次返回的场景,下面我们实现一个倒计时的例子:

In Object-c

- ( void )callProgress:(NSDictionary *) args :(void (^)(NSNumber * _Nullable result,BOOL complete))completionHandler
{
    value=10;
    hanlder=completionHandler;
    timer =  [NSTimer scheduledTimerWithTimeInterval:1.0
                                              target:self
                                            selector:@selector(onTimer:)
                                            userInfo:nil
                                             repeats:YES];
}
-(void)onTimer:t{
    if(value!=-1){
        hanlder([NSNumber numberWithInt:value--],NO);
    }else{
        hanlder(@"",YES);
        [timer invalidate];
    }
}

In javascript

dsBridge.call("callProgress", function (value) {
	document.getElementById("progress").innerText = value
})

完整的示例代码请参考demo工程。

Javascript 弹出框

DSBridge已经实现了 Javascript的弹出框函数(alert/confirm/prompt),这些对话框按钮、标签文字默认都是中文的,如果你想自定义这些文本可以参考 customJavascriptDialogLabelTitles API,如果你不想使用DSBridge实现的对话框,你可以通过设置DSUIDelegate 属性(是WKUIDelegate的代理属性)完全自定义。

另外注意,DSBridge实现的弹出框都是模态的,这会阻塞UI线程,如果你需要非模态的对话框,请参考disableJavascriptDialogBlock API.

API详细列表

下面是完整的API列表,详细的文档请移步:github.com/wendux/DSBr…

Object-C API

addJavascriptObject:(id) object namespace:(NSString *) namespace
removeJavascriptObject:(NSString *) namespace
callHandler:(NSString *) methodName arguments:(NSArray *) args]
callHandler:(NSString *) methodName completionHandler:(void (^)(id value))completionHandler
callHandler:(NSString *) methodName arguments:(NSArray *) args completionHandler:(void (^ )(id value))completionHandler
disableJavascriptDialogBlock:(bool) disable
setJavascriptCloseWindowListener:(void(^_Nullable)(void))callback
hasJavascriptMethod:(NSString*) handlerName
setDebugMode:(bool) debug
customJavascriptDialogLabelTitles:(NSDictionary*) dic

Javascript API

dsBridge.call(method,[arg,callback])
dsBridge.register(methodName|namespace,function|synApiObject)
dsBridge.registerAsyn(methodName|namespace,function|asyApiObject)
dsBridge.hasNativeMethod(handlerName,[type])
dsBridge.disableJavascriptDialogBlock(disable)

和 fly.js一起使用

当dsBridge遇见 Fly.js 时,将会打开一个新的世界。fly.js传送门

正如我们所知,在浏览器中,ajax请求受同源策略限制,不能跨域请求资源。然而, Fly.js 有一个强大的功能就是支持请求重定向:将ajax请求通过任何Javascript bridge重定向到端上,并且 Fly.js 官方已经提供的 dsBridge 的 adapter, 可以非常方便的协同dsBridge一起使用。由于端上没有同源策略的限制,所以 fly.js可以请求任何域的资源。

另一个典型的使用场景是在混合APP中,由于Fly.js 可以将所有ajax请求转发到端上,所以,开发者就可以在端上进行统一的请求管理、证书校验、cookie管理、访问控制等。

详情请参考 https://github.com/wendux/fly. (DSBridge Android版 demo中包含fly.js的示例)

最后

如果你喜欢 DSBridge, 欢迎star,以便更多的人知道它, 谢谢 ! 再次贴出DSBridge仓库链接:

DSBridge for IOS:github.com/wendux/DSBr…

DSBridge for Android: github.com/wendux/DSBr…