一直以來啊,覺得我們iOS跟js交互,并沒有多難。前有三方橋接,后有大系統(tǒng)庫。so easy嘛,所以一直沒有深入研究過。
我以為要是交互簡(jiǎn)單就行,我就可以專心吃雞!
好好吃雞,天天向上.gif
你以為的總是你以為的,干活嘍!吃雞能咋的,并不能!
下面看看什么背景,需求,導(dǎo)致我得把這個(gè)交互,原原本本的又梳理了一次。
背景
項(xiàng)目要在11.11這個(gè)大節(jié)日前上線商城功能,東西較多,所以部分功能使用H5,這樣分擔(dān)部分移動(dòng)端任務(wù)。
需求
- 完成網(wǎng)頁中某個(gè)活動(dòng)下的商品點(diǎn)擊進(jìn)入商品詳情
- 完成單個(gè)網(wǎng)頁的動(dòng)態(tài)化分享內(nèi)容
- 后臺(tái)最好寫一套內(nèi)容,完成安卓,iOS 兩端同時(shí)可交互
問題,以及解決
- 一個(gè)onclick的網(wǎng)頁交互沒問題,采用下面JS這個(gè)庫,沒問題,但是多參數(shù),安卓,iOS的方法格式不太一樣
---需要解決方法統(tǒng)一的問題
解決:iOS將方法分解成多參數(shù)的,下邊具體說了,就明白了。
1.有點(diǎn)擊事件的交互
單參數(shù)交互--//優(yōu)惠券獲取商品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>
//優(yōu)惠券獲取商品ID
- (void)redirection:(NSString *)goods_commonid;
//秒殺活動(dòng)獲取商品ID
@end
- iOS---在HYBJsObjCModel.m
- (void)redirection:(NSString *)goods_commonid{
//獲取到商品ID,進(jìn)行相關(guān)跳轉(zhuǎn)事件即可
}
多參數(shù)交互--通過點(diǎn)擊通過點(diǎn)擊事件獲取多個(gè)參數(shù)值[分享內(nèi)容]
先看下iOS多個(gè)參數(shù)的方法,與安卓,JS是不同的
//獲取分享的內(nèi)容
- (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>
//獲取分享的內(nèi)容
- (void)getShareTitle:(NSString *)title Desc:(NSString *)desc Icon:(NSString *)icon Url:(NSString *)url;
@end
- iOS---在HYBJsObjCModel.m
//獲取分享的內(nèi)容
- (void)getShareTitle:(NSString *)title Desc:(NSString *)desc Icon:(NSString *)icon Url:(NSString *)url {
}
2.點(diǎn)擊事件的交互無【獲取分享內(nèi)容為例】
==問題==:js不通過點(diǎn)擊方法,直接調(diào)用原生定義好的方法,安卓依然可以監(jiān)測(cè)到,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調(diào)用方法時(shí),ios網(wǎng)頁還沒有加載完畢,所以沒有js對(duì)象,不能夠監(jiān)測(cè)到交互事件
++如果H5監(jiān)測(cè)不到加載完畢,可采用方法如下++
采用iOS 原生調(diào)用js的方法,js方法里邊,再次調(diào)用ios原生,在網(wǎng)頁加載完畢的時(shí)候,進(jìn)行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);
};
//靜態(tài)獲取該網(wǎng)頁的數(shù)據(jù)流程
//1.網(wǎng)頁加載完畢,原生調(diào)用js的某個(gè)方法
//2.js獲取通知,通過調(diào)用ios原生方法,傳值
JSValue *Callback = self.jsContext[@"callJS"];
//傳值給web端
[Callback callWithArguments:@[@"喚起本地OC回調(diào)完成"]];
}
- 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>
/*雙引號(hào)里邊加單引號(hào),單引號(hào)里邊加雙引號(hào)*/
<script>
var callJS = function(){
alert("成功")
yulinjs.getShareTitleDescIconUrl(‘1’,’2’,’3’,’4’);
}
</script>
</body>
</html>
下面demo,一看就懂[https://pan.baidu.com/s/1miN2qhi]