混合开发Js bridge新秀-DSBridge iOS篇
这个DSBridge 和我之前开发做的混合开发 用的方式 很相似,所以觉得很是不错,推荐给你大家.
DSBridge-IOS:https://github.com/wendux/DSBridge-IOS
DSBridge-Android:https://github.com/wendux/DSBridge-Android
与WebViewJavascriptBridge的对比请移步 DSBridge VS WebViewJavascriptBridge。
原文链接:http://www.jianshu.com/p/3946605109ed
五分钟了解DSBridge
Web端
假设Native端实现了两个api: testSyn、testAsyn。参数以json传递, testSyn为同步api,执行结束后会直接返回结果,而testAsyn为一个异步api(可能会执行耗时操作),执行结束后,结果异步返回。下面我们看看web端如何调用。
Javascript调用Native
var bridge = getJsBridge();
var str=bridge.call("testSyn", {msg: "testSyn"});
bridge.call("testAsyn", {msg: "testAsyn"}, function (v) {
alert(v);
})
简单到不用解释!太优雅了。如果你体会不来,你也许应该去看看当今(马上将会成为历史)人气最高的WebViewJavascriptBridge ,相信你看完之后会回来的。
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接口约定如下:
- 返回值类型存在时为NSString、不存在时为void。
- 参数以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:@,@"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对话框,您可以不做处理,也可以自定义。值得一提的是js 在调用alert函数正常情况下只要用户没有关闭alert对话框,js代码是会阻塞的,但是考虑到alert 对话框只有一个确定按钮,也就是说无论用户关闭还是确定都不会影响js代码流程,所以DWebview中在弹出alert对话框时会先给js返回,这样一来js就可以继续执行,而提示框等用户关闭时在关闭即可。如果你就是想要阻塞的alert,可以自定义。而DWebview的prompt、comfirm实现完全符合ecma标准,都是阻塞的。
请不要手动设置DUIwebview的delegate属性,因为DUIwebview在内部已经设置了该属性,如果您需要自己处理页面加载过程,请设置WebEventDelegate属性。
混合开发Js bridge新秀-DSBridge iOS篇的更多相关文章
- 【Flutter 混合开发】添加 Flutter 到 iOS
Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-iOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...
- H5混合开发中android终端和ios终端常见的兼容问题1
转自 https://blog.csdn.net/xuehu837769474/article/details/80603898 1.安卓浏览器看背景图片,有些设备会模糊. 用同等比例的图片在PC机上 ...
- H5混合开发中android终端和ios终端常见的兼容问题2
转自 https://www.cnblogs.com/stoneniqiu/p/6077112.html 1.ios键盘挡住输入框. setInterval(function () { if (doc ...
- 一、React Native 搭建开发环境(1)(Mac OS - IOS项目篇)
React Native是Facebook推出的一个开发IOS和安卓APP的技术.至于更多的详情,这里不再描述,大家可以自行百度它的定义. 原因:由于我想在一台电脑上同时开发IOS和Android两个 ...
- .NET混合开发解决方案12 网页JS调用C#方法访问WinForm或WPF窗体
系列目录 [已更新最新开发文章,点击查看详细] WebView2控件应用详解系列博客 .NET桌面程序集成Web网页开发的十种解决方案 .NET混合开发解决方案1 WebView2简介 .NE ...
- Unity iOS混合开发界面切换思路
Unity iOS混合开发界面切换思路 最近有很多博友QQ 私信 或则 留言联系我,请教iOS和Unity界面之前相互切换的问题,源代码就不私下发你们了,界面跳转功能的代码我直接贴到下面好了,顺带说i ...
- android混合开发,webview的java与js互操作
android原生应用,用webview加载应用中的网页,并且java代码与js代码可以互相操作. 这是混合开发的基石,最基本也最重要的东西,实验代码在这里. 概括说说—— java调js:调用web ...
- iOS - 混合开发
5.oc 与 js 混合开发 PhoneGap 专门做混合开发的,已经被另一个公司收购. WebViewJavascriptBridge 国内用的比较多 混合开发的好处:跨平台性.H5开发的时间成本, ...
- ios&h5混合开发项目仿app页面跳转优化
前言:本人原本是ios开发工程师,但由于现今H5的兴起,行内刮起了一阵混合开发的风气,趁着这股劲,我也学了前端开发,不说研究的多深,但也能胜任日常的开发工作.长话短说,现今的混合开发应该还处于摸索阶段 ...
随机推荐
- Youtube 视频下载
Youtube 视频下载 由于特殊原因,需要下载 Youtube 的视频. https://www.clipconverter.cc/
- bzoj 2535 && bzoj 2109 [Noi2010]Plane 航空管制——贪心
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2535 https://www.lydsy.com/JudgeOnline/problem.p ...
- 树的遍历——pat1043
http://pat.zju.edu.cn/contests/pat-a-practise/1043 给予N个数字组成二叉搜索树,判断这个数列是否由先序遍历得出或是镜像先序遍历得出,若是则输出相应的后 ...
- wdlinux中apache配置反向代理模块
想要在.htaccess中开启反向代理功能都不行[apache中没有mod_proxy模块] .htaccess 文件内容如下 RewriteEngine On RewriteBase / Rewri ...
- postman md5加密例子
引用方法 {{md5}} 参考:https://www.jianshu.com/p/5a49d1deaf69 实例:
- 二、Spark在Windows下的环境搭建
由于Spark是用Scala来写的,所以Spark对Scala肯定是原生态支持的,因此这里以Scala为主来介绍Spark环境的搭建,主要包括四个步骤,分别是:JDK的安装,Scala的安装,Spar ...
- SHUTDOWN: waiting for active calls to complete
Problem Description: ==================== You are attempting to shut down the database and the data ...
- Android关于inflate的root参数
最近在用View inflate(Context context, int resource, ViewGroup root)方法时,在第三个参数root上碰到了点麻烦. 一般在写ListView的a ...
- Centos 部署Cobbler系统
一.简介 Cobbler 可以用来快速建立 Linux 网络安装环境,它已将 Linux 网络安装的技术门槛,从大专以上文化水平,成功降低到初中以下,连补鞋匠都能学会.(~..~) 二.安装环境以及资 ...
- Web(Easy UI)
HTML菜鸟教程 http://www.runoob.com/html/html-tables.html EasyUI combobox下拉多选框的实现 https://www.cnblogs.com ...