前言
公司的客户有许多传统行业,他们的需求有绝大多数是OA办公模块。针对比较简单的业务,例如:请假申请,出差申请等。为了节省开发成本,使用H5版本开发,节省开发成本,但有些功能可能涉及到调用原生的功能(比如陀螺仪,录音),或者H5比较困难实现的功能。
功能
Vue+VantUI进行H5的开发,同时使用 DSBridge 进行交互。
注意点
之前iOS使用的版本是2.0.6版本,使用 DUIWebView 去加载的页面,因为选图的组件使用的是原生,要解决跨域问题。当然这是不好的方案。首先不安全,其次,后来有客户反映,iOS12之后,加载部分页面后,界面就卡死了。之后就升级到最新的版本3.0.6,升级到 DWKWebView,选图的功能暂时是把图片转成Base64字符串,加上 data:image/png;base64, 协议,提供给img 标签使用。
具体使用
LKH5ContentViewController
加载H5内容的容器
@property (strong, nonatomic) DWKWebView *webview;
@property (strong, nonatomic) LKH5Api *h5Api;
self.webview.navigationDelegate = self;
[self.webview addJavascriptObject:self.h5Api namespace:nil];
#pragma mark - WKNavigationDelegate
LKH5Api
提供所有原生API的工具
同步获取原生的数据
- (NSString *)getSyncMobileBase:(NSDictionary *)args{
// args 是 H5 端传过来的参数
NSDictionary *params = CURRENTUSER.jwt ? : @{};
NSMutableDictionary *baseInfo = [NSMutableDictionary dictionary];
baseInfo[@"jwt"] = params;
baseInfo[@"appurl"] = @""
baseInfo[@"ip"] = @"";
baseInfo[@"port"] = @"";
return [baseInfo mj_JSONString];
}
异步获取原生的数据
- (void)getMobileBase:(NSDictionary *)args :(JSCallback)handler{
// args 是 H5 端传过来的参数
dispatch_async(dispatch_get_main_queue(), ^{
NSDictionary *params = CURRENTUSER.jwt ? : @{};
NSMutableDictionary *baseInfo = [NSMutableDictionary dictionary];
baseInfo[@"jwt"] = params;
baseInfo[@"appurl"] = @"";
baseInfo[@"ip"] = @"";
baseInfo[@"port"] = @"";
handler([baseInfo mj_JSONString],YES);
});
}
H5端调用
<!DOCTYPE html>
...
<body>
<button id="getMobileBase" type="button" onclick="getMobileBase()">获取MobileBase</button>
<script type="text/javascript">
function getMobileBase() {
LKBridge.getMobileBase({
complete:function(jsonStr){
document.getElementById('getMobileBase').innerHTML = jsonStr
}
})
}
</script>
</body>
</html>
在Native 中调用JS API
[self.webview callHandler:@"registerMobileBase" arguments:@[[baseInfo mj_JSONString]] completionHandler:^(NSString * value){
HTLog(@"%@",value);
}];
LKBridge 是我们中转的一层,主要实现 dsBridge 调用原生的API的过程。
window.LKBridge = {
getMobileBase:function(obj) {
dsBridge.call('getMobileBase', obj.complete);
}
}
效果
其他
若是简单的交互,也可以通过截取此url,与js交互。
使用场景:比如加载 echarts 柱状图,点击某根柱子,调整具体的原生的VC页面。
<!DOCTYPE html>
<html>
...
window.location.href='luculent:'+mNoArr[param.dataIndex]+'||'+titleArr[param.dataIndex];
</html>
WKWebViewDelegate
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
//将url转换为string
NSString *requestString = [[navigationAction.request URL] absoluteString];
//hasPrefix 判断创建的字符串内容是否以luculent:字符开始
if ([requestString hasPrefix:@"luculent:"]){
decisionHandler(WKNavigationActionPolicyCancel);
}else {
decisionHandler(WKNavigationActionPolicyAllow);
}
}
UIWebViewDelegate
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
NSString *requestString = [[[request URL] absoluteString]stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
if ([[requestString componentsSeparatedByString:@":"].firstObject isEqualToString:@"luculent"]) {
...
return NO;
}
return YES;
}