跨平台Js bridge新秀-DSBridge IOS篇

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 WebViewJavascriptBridgeandroid

原文连接:http://www.jianshu.com/p/3946605109edios

五分钟了解DSBridgegit

Web端

假设Native端实现了两个api: testSyn、testAsyn。参数以json传递, testSyn为同步api,执行结束后会直接返回结果,而testAsyn为一个异步api(可能会执行耗时操做),执行结束后,结果异步返回。下面咱们看看web端如何调用。github

Javascript调用Native

var bridge = getJsBridge();
var str=bridge.call("testSyn", {msg: "testSyn"});
bridge.call("testAsyn", {msg: "testAsyn"}, function (v) {
  alert(v);
})
复制代码

简单到不用解释!太优雅了。若是你体会不来,你也许应该去看看当今(立刻将会成为历史)人气最高的WebViewJavascriptBridge ,相信你看完以后会回来的。web

DSBridge虽然说简单,但为了让你了然于胸,仍是给出官方解释:objective-c

getJsBridge

功能:获取javascript bridge对象。

等等,貌似和我以前使用的其余库不同,难道不须要像WebViewJavascriptBridge那样先声明一个setupWebViewJavascriptBridge的回调?你有这种疑问很正常,先给出答案:不须要,DSBridge不须要前端任何安装代码,随用随取。DSBridge的设计原则就是:让三端使用方式都是最简单的! DSBridge获取bridge时,不依赖任何回调,也无需等待页面加载结束(若是您体会不到,能够对比WebViewJavascriptBridge 前端调用方式)。ps: 这在ios>=8,android>sdk19上测试都没问题, DSBridge也对ios7.0-8.0,android sdk16-19之间的版本作了兼容,可是考虑到测试覆盖面的问题,建议全部代码都在dom ready以后执行。

bridge.call(method,[args,callback])

功能:调用Native api

method: api函数名

args:参数,类型:json, 可选参数

callback(String returnValue):仅调用异步api时须要.

同步调用

若是你是一名经验丰富的开发者,想必看到第二行时已然眼睛一亮,想一想node最被诟病的是什么,目前跨平台的jsbridge中没有一个能支持同步,全部须要获取值的调用都必须传一个回调,若是调用逻辑比较复杂,必将会出现“callback hell”。然而,DSBridge完全改变了这一点。支持同步是DSBridge的最大亮点之一

异步调用

对于一些比较耗时的api, DSBridge提供了异步支持,正如上例第三行代码所示,此时你须要传一个回调(若是没有参数,回调可做为第二个参数),当api完成时回调将会被调用,结果以字符串的形式传递。

供Native调用Javascript api

假设网页中要提供一个函数test供native调用,只要将函数声明为全局函数便可:

function test(arg1,arg2){
  return arg1+arg2;
}
复制代码

若是你的代码是在一个闭包中,将函数挂在window上便可:

window.test=function(arg1,arg2){
  	return arg1+arg2;
}	
复制代码

这样一来端上便可调用。

IOS端

实现Api

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接口约定以下:

  1. 返回值类型存在时为NSString、不存在时为void。
  2. 参数以JSON传递; DSBridge会将js参数自动转化为NSDictionary

注:JsApiTest.m中实现的方法能够不在JsApiTest.h中声明

注册Api

DWebview * webview=[[DWebview alloc] initWithFrame:bounds];
jsApi=[[JsApiTest alloc] init];
webview.JavascriptInterfaceObject=jsApi;
复制代码

DWebview是sdk中提供的,您也可使用其它两个,这将在后文介绍。

可见对于Native来讲,经过一个单独的类实现js api, 而后直接注册(而不须要像其它一些js bridge每一个api都要单独注册),这样不只很是简单,并且结构清晰。

调用Javascript

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工程。

关于DWebview

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

相关文章
相关标签/搜索