源碼鏈接
在工作中會(huì)出現(xiàn)許多原生不好實(shí)現(xiàn)蛇更,但是h5的話就很簡(jiǎn)單,或者是原生做來不及就讓前端寫界面赛糟,原生就寫個(gè)交互這種情況派任。這時(shí)候原生需要做的就是實(shí)現(xiàn)與js交互
。
js代碼
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div style="margin-top: 100px">
<h1>Objective-C和JavaScript交互</h1>
<input type="button" value="CallCamera" onclick="WTK.callCamera()">
</div>
<div>
<input type="button" value="Share" onclick="callShare()">
</div>
<script>
var callShare = function() {
var shareInfo = JSON.stringify({"title": "標(biāo)題", "desc": "內(nèi)容", "shareUrl": "http://www.reibang.com/u/f3e780fd1a4e"});
WTK.share(shareInfo);
}
var picCallback = function(photos) {
alert(photos);
}
var shareCallback = function(){
alert('success');
}
</script>
</body>
</html>
解釋一下JS代碼
定義兩個(gè)按鈕璧南,點(diǎn)擊方法一個(gè)調(diào)用WTK.callCamera()
方法掌逛,這個(gè)WTK是原生的,OC定義的司倚,方法也是原生的豆混。具體實(shí)現(xiàn)下面會(huì)將。另一個(gè)調(diào)用js的callShare
方法动知。在callShare
方法中定義了json字符串皿伺,然后調(diào)用原生方法WTK.share(param)
,并把json字符串傳了過去。
另外定義了兩個(gè)方法picCallBack
和shareCallback
盒粮。第一個(gè)方法需要參數(shù)心傀。 這兩個(gè)方法用于測(cè)試OC調(diào)用JS方法。
OC代碼
需要導(dǎo)入<JavaScriptCore/JavaScriptCore.h>
首先定義協(xié)議
@protocol JSObjDelegate <JSExport>
- (void)callCamera;
- (void) share:(NSString *)shareInfo;
@end
需要說明的是拆讯,協(xié)議需要繼承JSExport
脂男。這個(gè)協(xié)議官方也寫的很清楚,JS調(diào)用原生方法的時(shí)候种呐,這個(gè)方法需要被外部看到宰翅,通過這個(gè)協(xié)議來讓外部看到。這個(gè)協(xié)議并沒有方法爽室,使用的時(shí)候需要繼承這個(gè)協(xié)議來使用汁讼。
@interface TwoViewController ()<UIWebViewDelegate,JSObjDelegate>
@property(nonatomic,strong)UIWebView *webView;
@property(nonatomic,strong)JSContext *jsContext;
@end
定義一個(gè)屬性為JSContext的對(duì)象jsContext,通過這個(gè)對(duì)象來實(shí)現(xiàn)與js交互。
關(guān)于web的實(shí)現(xiàn)不再貼出嘿架,需要注意的是要實(shí)現(xiàn)webView的代理瓶珊,在代理方法中做一些準(zhǔn)備工作。
web代理方法
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
self.jsContext[@"WTK"] = self;
self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *ex){
context.exception = ex;
NSLog(@"異常信息%@",ex);
};
}
這web加載完成的代理方法中耸彪,實(shí)現(xiàn)jsContext
的一系列操作金砍。
- 首先是使用KVC獲得jsContext對(duì)象揽碘。
- 然后對(duì)js中的
WTK
進(jìn)行賦值绊寻,也就是上面說的JS調(diào)用WTK.callCamera()
方法中的WTK哥纫。
實(shí)現(xiàn)JSExport代理方法
這里是實(shí)現(xiàn)繼承于JSExport的代理JSObjDelegate
// JSObjDelegate
- (void)callCamera
{
NSLog(@"調(diào)用攝像頭");
JSValue *picCallBack = self.jsContext[@"picCallback"];
[picCallBack callWithArguments:@[@"wangtongke"]];
}
- (void) share:(NSString *)shareInfo {
NSLog(@"%@",shareInfo);
JSValue *shareCallBack = self.jsContext[@"shareCallback"];
[shareCallBack callWithArguments:nil];
}
這個(gè)callCamera是js的點(diǎn)擊方法,也就是js來調(diào)用的方法召川。
JSValue為OC獲取JS對(duì)象的類南缓,這里通過jsContext來獲取js名為picCallBack的對(duì)象,也就是js自定義的一個(gè)方法荧呐,需要一個(gè)任意類型的參數(shù)(不清楚的可以看上面js代碼)汉形。
然后使用jsCallBack
這個(gè)對(duì)象執(zhí)行callWithArguments:
方法,這個(gè)方法為OC主動(dòng)調(diào)用js的方法倍阐,可以傳參給js获雕。
下面這個(gè)share:
方法,也是js的點(diǎn)擊方法收捣,傳了一個(gè)參數(shù)shareInfo
届案。
然后通過JSValue調(diào)用js的shareCallback
方法。
下面是效果圖罢艾。
點(diǎn)擊call按鈕楣颠,OC回調(diào)js方法并傳值。