三端易用的現代跨平臺JavaScript Bridge之 IOS篇

wendux發表於2018-02-26

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…

相關文章