一直以来啊,觉得我们iOS跟js交互,并没有多难。前有三方桥接,后有大系统库。so easy嘛,所以一直没有深入研究过。
我以为要是交互简单就行,我就可以专心吃鸡!
你以为的总是你以为的,干活喽!吃鸡能咋的,并不能!
下面看看什么背景,需求,导致我得把这个交互,原原本本的又梳理了一次。
背景
项目要在11.11这个大节日前上线商城功能,东西较多,所以部分功能使用H5,这样分担部分移动端任务。
需求
- 完成网页中某个活动下的商品点击进入商品详情
- 完成单个网页的动态化分享内容
- 后台最好写一套内容,完成安卓,iOS 两端同时可交互
问题,以及解决
- 一个onclick的网页交互没问题,采用下面JS这个库,没问题,但是多参数,安卓,iOS的方法格式不太一样
---需要解决方法统一的问题
解决:iOS将方法分解成多参数的,下边具体说了,就明白了。
1.有点击事件的交互
单参数交互--//优惠券获取商品ID
- H5写法
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div style="margin-top:20px">
<h2>JS与OC交互</h2>
<input type="button" value="唤醒本地方法(redirection)" onclick="yulinjs.redirection('123')">
</div>
</body>
</html>
- iOS---在HYBJsObjCModel.h
@protocol JavaScriptObjectiveCDelegate <JSExport>
//优惠券获取商品ID
- (void)redirection:(NSString *)goods_commonid;
//秒杀活动获取商品ID
@end
- iOS---在HYBJsObjCModel.m
- (void)redirection:(NSString *)goods_commonid{
//获取到商品ID,进行相关跳转事件即可
}
多参数交互--通过点击通过点击事件获取多个参数值[分享内容]
先看下iOS多个参数的方法,与安卓,JS是不同的
//获取分享的内容
- (void)getShareTitle:(NSString *)title Desc:(NSString *)desc Icon:(NSString *)icon Url:(NSString *)url;
- H5---
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div style="margin-top:20px">
<h2>JS与OC交互</h2>
<input type="button" value="唤醒本地方法(getShareTitleDescIconUrl)" onclick=“yulinjs.getShareTitleDescIconUrl(‘1’,’2’,’3’,’4’)”>
</div>
</body>
</html>
- iOS----在HYBJsObjCModel.h
@protocol JavaScriptObjectiveCDelegate <JSExport>
//获取分享的内容
- (void)getShareTitle:(NSString *)title Desc:(NSString *)desc Icon:(NSString *)icon Url:(NSString *)url;
@end
- iOS---在HYBJsObjCModel.m
//获取分享的内容
- (void)getShareTitle:(NSString *)title Desc:(NSString *)desc Icon:(NSString *)icon Url:(NSString *)url {
}
2.点击事件的交互无【获取分享内容为例】
==问题==:js不通过点击方法,直接调用原生定义好的方法,安卓依然可以监测到,iOS 不行
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div style="margin-top:20px">
<h2>JS与OC交互</h2>
<body> <script type="text/javascript">setTimeout('yulinjs.redirection('123');',2000)</script></body>
</body>
</html>
==原因== :js调用方法时,ios网页还没有加载完毕,所以没有js对象,不能够监测到交互事件
++如果H5监测不到加载完毕,可采用方法如下++
采用iOS 原生调用js的方法,js方法里边,再次调用ios原生,在网页加载完毕的时候,进行js,ios交互
- ios代码如下
- (void)webViewDidFinishLoad:(UIWebView *)webView {
self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
self.jsContext[@"yulinjs"] = self;
self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
context.exception = exceptionValue;
NSLog(@"异常信息:%@", exceptionValue);
};
//静态获取该网页的数据流程
//1.网页加载完毕,原生调用js的某个方法
//2.js获取通知,通过调用ios原生方法,传值
JSValue *Callback = self.jsContext[@"callJS"];
//传值给web端
[Callback callWithArguments:@[@"唤起本地OC回调完成"]];
}
- H5代码如下
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<div style="margin-top:20px">
<h2>JS与OC交互</h2>
/*双引号里边加单引号,单引号里边加双引号*/
<script>
var callJS = function(){
alert("成功")
yulinjs.getShareTitleDescIconUrl(‘1’,’2’,’3’,’4’);
}
</script>
</body>
</html>
下面demo,一看就懂[https://pan.baidu.com/s/1miN2qhi]