一突颊、說明
這篇文章記錄自己在研究OC與JS交互中的所得,以及遇到的問題與解決
由于蘋果的審核時(shí)間太漫長颁糟,一次審核不過,那又將進(jìn)入另一個(gè)漫長的審核期桑谍。為了能在開發(fā)中方便更新,公司要求在項(xiàng)目中使用HTML5洗显,這樣就涉及到OC與JS的交互外潜, 在經(jīng)過一段時(shí)間的摸索之后,將自己的研究記錄下來挠唆,以做備忘处窥。
OC與JS的交互實(shí)現(xiàn)方式有很多,之前用的比較多的是WebViewJavaScriptBridge玄组,但在IOS7之后滔驾,蘋果將JavaScriptCore框架開放。因此俄讹,這篇文章不講理論,主要講的是JavaScriptCore的實(shí)際使用哆致。
文中所用的項(xiàng)目JavaScriptCoreDemo
廢話說完了,下面進(jìn)入正題
二、Demo項(xiàng)目中功能介紹
Demo首頁
這個(gè)demo主要分為了三個(gè)部分來:
1.JS Call OC? , JS調(diào)用OC的函數(shù)
2.OC Call JS? , OC調(diào)用JS的函數(shù)
3.一個(gè)繪圖的例子
在做OC與JS交互工作之前患膛,我們需要做些準(zhǔn)備工作
1.導(dǎo)入JavaScriptCore的頭文件
#import
2.用webView加載HTML文件,這里用的是本地HTML;
- (void)viewDidLoad{[superviewDidLoad];// Do any additional setup after loading the view from its nib.self.title=@"js call oc";NSString*path = [[[NSBundlemainBundle] bundlePath]? stringByAppendingPathComponent:@"JSCallOC.html"];NSURLRequest*request = [NSURLRequestrequestWithURL:[NSURLfileURLWithPath:path]];[self.webViewloadRequest:request];}
3.在JS交互中摊阀,很多事情都是在webView的delegate方法中完成的,通過JSContent創(chuàng)建一個(gè)使用JS的環(huán)境,所以這里胞此,我們先將self.content在這里面初始化;
- (void)webViewDidFinishLoad:(UIWebView*)webView{//初始化
contentself.context= [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];// 打印異常,由于JS的異常信息是不會(huì)在OC中被直接打印的,所以我們在這里添加打印異常信息,self.context.exceptionHandler=^(JSContext *context, JSValue *exceptionValue){? ? context.exception= exceptionValue;NSLog(@"%@", exceptionValue);};}
三臣咖、實(shí)際操作中 JS call OC
先來看demo
JS Call OC
這個(gè)頁面整個(gè)都是通過HTML實(shí)現(xiàn)的,
1 計(jì)算階乘:在輸入框中輸入一個(gè)數(shù)字漱牵,然后在OC中計(jì)算出結(jié)果夺蛇,最后顯示在HTML的頁面上;
2 測試log:點(diǎn)擊后酣胀,在后臺(tái)打印測試數(shù)據(jù)蚊惯;
3 OC原生Alert :點(diǎn)擊后,彈出OC的提示框灵临;
4 addSubView:點(diǎn)擊后,在OC中添加一個(gè)View趴荸;
5 push to second ViewController :跳轉(zhuǎn)到下一個(gè)界面
總結(jié):以上功能都是在OC獲取HTML中按鈕的點(diǎn)擊事件,在后在OC中實(shí)現(xiàn)功能
??如何獲取HTML中的點(diǎn)擊事件呢??
在HTML中,為一個(gè)元素添加點(diǎn)擊時(shí)間有兩種寫法
或者
如果是第一種方法,
那么就要用JSExport協(xié)議關(guān)聯(lián)native的方法,要在webView的delegate里面添加
// 以 JSExport 協(xié)議關(guān)聯(lián) native 的方法self.content[@"native"] =self;
添加完之后,要聲明一個(gè)繼承JSExport的協(xié)議,協(xié)議中聲明供JS使用的OC的方法
@protocolTestJSExportJSExportAs(calculateForJS/** handleFactorialCalculateWithNumber 作為js方法的別名 */, - (void)handleFactorialCalculateWithNumber:(NSNumber*)number );- (void)pushViewController:(NSString*)view title:(NSString*)title;-(void)log:(NSString*)l;@end
在OC中實(shí)現(xiàn)這些方法,這樣就完成了!
如果是第二章方法,則只需要通過block的形式關(guān)聯(lián)JavaScript function就可以了!
self.context[@"log"] = ^(NSString*str){NSLog(@"%@", str);};
三儒溉、OC調(diào)用JS
OC調(diào)用JS
在這個(gè)例子中,界面的所有View都是OC創(chuàng)建的发钝,點(diǎn)擊“交給JS處理計(jì)算階乘”后顿涣,將textfild的數(shù)據(jù)傳給JS,JS計(jì)算完成后在返回來酝豪!
這里面首先要獲取JS里面的計(jì)算函數(shù)涛碑,在OC中,所有表示JS中對(duì)象孵淘,都用JSValue來創(chuàng)建蒲障,通過objectForKeyedSubscript方法或者直接使用下標(biāo)的方法獲取JS對(duì)象,然后使用callWithArguments方法來執(zhí)行函數(shù)
// 方法一.? JSValue *function = [self.context objectForKeyedSubscript:@"factorial"];// 方法二.JSValue * function =self.context[@"factorial"];JSValue *result = [function callWithArguments:@[inputNumber]];self.showLable.text= [NSStringstringWithFormat:@"%@", [result toNumber]];
四瘫证、demo之外(慢慢在總結(jié))
1.JS注入
2.在OC中為JS創(chuàng)建對(duì)象
......
零碎的補(bǔ)充1:對(duì)于JS 函數(shù)中,參數(shù)中有函數(shù)的,在OC中用JSValue接收
// 比如:JS代碼functionmyFunc({"text":"這里是文字","callbackFun":function(string){alert'string'}});//OC代碼中在.h的protocol中聲明JS要調(diào)用的OC方法//.h protocol中,函數(shù)名稱要和JS中相同,這里接收的參數(shù)為JSValueJSExportAs(myFunc, -(void) myFunc:(JSValue*)value);//在.m文件中,實(shí)現(xiàn)myFunc方法-(void) myFunc:(JSValue*)value{NSString * text = [valuevalueForProperty:@"text"];//打印"這里是文字"JSValue * func =? [valuevalueForProperty:@"callbackFun"];//這里是JS參數(shù)中的func;//調(diào)用這個(gè)函數(shù)[func callWithArguments:@[@"這里是參數(shù)"]];}
原文鏈接:http://www.reibang.com/p/cdaf9bc3d65d
著作權(quán)歸作者所有揉阎,轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),并標(biāo)注“簡書作者”背捌。