DSBridge是目前地球上最好的IOS/Android javascript bridge. 沒有之一 !javascript
依然是博客搬家,若已閱讀過,請跳過。前端
DSBridge-IOS:https://github.com/wendux/DSBridge-IOSjava
DSBridge-Android:https://github.com/wendux/DSBridge-Androidnode
與WebViewJavascriptBridge的對比請移步 DSBridge VS WebViewJavascriptBridge。android
原文連接:http://www.jianshu.com/p/3946605109edios
五分鐘瞭解DSBridgegit
假設Native端實現了兩個api: testSyn、testAsyn。參數以json傳遞, testSyn爲同步api,執行結束後會直接返回結果,而testAsyn爲一個異步api(可能會執行耗時操做),執行結束後,結果異步返回。下面咱們看看web端如何調用。github
var bridge = getJsBridge();
var str=bridge.call("testSyn", {msg: "testSyn"});
bridge.call("testAsyn", {msg: "testAsyn"}, function (v) {
alert(v);
})
複製代碼
簡單到不用解釋!太優雅了。若是你體會不來,你也許應該去看看當今(立刻將會成爲歷史)人氣最高的WebViewJavascriptBridge ,相信你看完以後會回來的。web
DSBridge雖然說簡單,但爲了讓你瞭然於胸,仍是給出官方解釋:objective-c
功能:獲取javascript bridge對象。
等等,貌似和我以前使用的其餘庫不同,難道不須要像WebViewJavascriptBridge那樣先聲明一個setupWebViewJavascriptBridge的回調?你有這種疑問很正常,先給出答案:不須要,DSBridge不須要前端任何安裝代碼,隨用隨取。DSBridge的設計原則就是:讓三端使用方式都是最簡單的! DSBridge獲取bridge時,不依賴任何回調,也無需等待頁面加載結束(若是您體會不到,能夠對比WebViewJavascriptBridge 前端調用方式)。ps: 這在ios>=8,android>sdk19上測試都沒問題, DSBridge也對ios7.0-8.0,android sdk16-19之間的版本作了兼容,可是考慮到測試覆蓋面的問題,建議全部代碼都在dom ready以後執行。
功能:調用Native api
method: api函數名
args:參數,類型:json, 可選參數
callback(String returnValue):僅調用異步api時須要.
同步調用
若是你是一名經驗豐富的開發者,想必看到第二行時已然眼睛一亮,想一想node最被詬病的是什麼,目前跨平臺的jsbridge中沒有一個能支持同步,全部須要獲取值的調用都必須傳一個回調,若是調用邏輯比較複雜,必將會出現「callback hell」。然而,DSBridge完全改變了這一點。支持同步是DSBridge的最大亮點之一。
異步調用
對於一些比較耗時的api, DSBridge提供了異步支持,正如上例第三行代碼所示,此時你須要傳一個回調(若是沒有參數,回調可做爲第二個參數),當api完成時回調將會被調用,結果以字符串的形式傳遞。
假設網頁中要提供一個函數test供native調用,只要將函數聲明爲全局函數便可:
function test(arg1,arg2){
return arg1+arg2;
}
複製代碼
若是你的代碼是在一個閉包中,將函數掛在window上便可:
window.test=function(arg1,arg2){
return arg1+arg2;
}
複製代碼
這樣一來端上便可調用。
API的實現很是簡單,只須要將您要暴漏給js的api放在一個類中,而後統一註冊便可。
//JsApiTest.m
@implementation JsApiTest
- (NSString *) testSyn:(NSDictionary *) args
{
return [(NSString *)[args valueForKey:@"msg"] stringByAppendingString:@"[ syn call]"];
}
- (void) testAsyn:(NSDictionary *) args :(void (^)(NSString * _Nullable result))handler
{
handler([(NSString *)[args valueForKey:@"msg"] stringByAppendingString:@"[ asyn call]"]);
}
@end
複製代碼
testSyn爲同步api, js在調用同步api時會等待native返回,返回後js繼續往下執行。
testAsyn爲異步api, 異步操做時調用handler.complete通知js,此時js中設置的回調將會被調用。
爲了在ios和android平臺下兼容,對IOS端Native API接口約定以下:
注:JsApiTest.m中實現的方法能夠不在JsApiTest.h中聲明
DWebview * webview=[[DWebview alloc] initWithFrame:bounds];
jsApi=[[JsApiTest alloc] init];
webview.JavascriptInterfaceObject=jsApi;
複製代碼
DWebview是sdk中提供的,您也可使用其它兩個,這將在後文介紹。
可見對於Native來講,經過一個單獨的類實現js api, 而後直接註冊(而不須要像其它一些js bridge每一個api都要單獨註冊),這樣不只很是簡單,並且結構清晰。
DWebView提供了兩個api用於調用js
//調用js api(函數)
-(void)callHandler:(NSString *)methodName arguments:(NSArray * _Nullable)args
completionHandler:(void (^)(NSString * _Nullable))completionHandler;
//執行任意js代碼
- (void)evaluateJavaScript:(NSString *)javaScriptString
completionHandler:(void (^ _Nullable)(NSString * _Nullable))completionHandler;
複製代碼
callHandler中,methodName 爲js函數名,args爲參數數組,能夠接受數字、字符串等。
兩個函數中completionHandler爲完成回調,用於獲取js執行的結果。
調用時機
DWebview只有在javascript context初始化成功後才能正確執行js代碼,而javascript context初始化完成的時機通常都比整個頁面加載完畢要早,隨然DSBridge能捕獲到javascript context初始化完成的時機,可是一些js api可能聲明在頁面尾部,甚至單獨的js文件中,若是在javascript context剛初始化完成就調用js api, 此時js api 可能尚未加載,因此會失敗,爲此專門提供了一個api設置一個回調,它會在頁面加載結束後調用,爲了和didpagefinished區分,咱們取名以下:
- (void)setJavascriptContextInitedListener:(void(^_Nullable)(void))callback;
複製代碼
如果端上主動調用js,請在此回調中進行 。示例以下:
__block DWebview * _webview=webview;
[webview setJavascriptContextInitedListener:^(){
[_webview callHandler:@"test"
arguments:[[NSArray alloc] initWithObjects:@1,@"hello", nil]
completionHandler:^(NSString * value){
NSLog(@"%@",value);
}];
}];
複製代碼
完整的示例請查看demo工程。
SDK中有三個webview:
DWKwebview:繼承自WKWebView,內部已經實現js prompt、alert、confirm函數對應的對話框。
DUIwebview:繼承自UIWebView
DWebview:自定義view, 內部在ios8.0如下會使用DUIwebview, 大於等於8.0會使用DWKwebview。
全部的webview除了都實現了上述api以外,提供了一個加載網頁的便捷函數:
- (void)loadUrl: (NSString *) url;
複製代碼
您能夠根據具體業務使用任意一個,不過通常狀況下優先選用DWebview,它在新設備上更省資源,效率更高。
DWebview還提供了一些其它api和屬性,具體請查看其頭文件,須要特殊說明的是,有一個api:
- (id _Nullable) getXWebview;
複製代碼
它能夠返回DWebview內部使用的真實webview, 值會是DUIwebview和DWKwebview的實例之一,您能夠經過isKindOfClass來判斷,吃函數主要用於擴展DWebview,下面能夠看一下loadRequest的大概實現:
- (void)loadRequest:(NSURLRequest *)request
{
id webview=[self getXWebview];
if([webview isKindOfClass:[DUIwebview class]]){
[(DUIwebview *)webview loadRequest:request];
}else{
[(DWKwebview *)webview loadRequest:request];
}
}
複製代碼
DWebview已經實現 alert、prompt、comfirm對話框,您能夠不作處理,也能夠自定義。
請不要手動設置DUIwebview的delegate屬性,由於DUIwebview在內部已經設置了該屬性,若是您須要本身處理頁面加載過程,請設置WebEventDelegate屬性。
若是你以爲不錯,麻煩star一下哦!多謝支持😄。若有問題,歡迎反饋,wechat: Demons-du