一、說明
這篇文章記錄自己在研究OC與JS交互中的所得,以及遇到的問題與解決
由于蘋果的審核時間太漫長,一次審核不過,那又將進(jìn)入另一個漫長的審核期。為了能在開發(fā)中方便更新,公司要求在項目中使用HTML5,這樣就涉及到OC與JS的交互, 在經(jīng)過一段時間的摸索之后,將自己的研究記錄下來,以做備忘。
OC與JS的交互實現(xiàn)方式有很多,之前用的比較多的是WebViewJavaScriptBridge,但在IOS7之后,蘋果將JavaScriptCore框架開放。因此,這篇文章不講理論,主要講的是JavaScriptCore的實際使用。
文中所用的項目JavaScriptCoreDemo
廢話說完了,下面進(jìn)入正題
二、Demo項目中功能介紹

Demo首頁
這個demo主要分為了三個部分來:
1.JS Call OC? , JS調(diào)用OC的函數(shù)
2.OC Call JS? , OC調(diào)用JS的函數(shù)
3.一個繪圖的例子
在做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)建一個使用JS的環(huán)境,所以這里,我們先將self.content在這里面初始化;
- (void)webViewDidFinishLoad:(UIWebView*)webView{//初始化
contentself.context= [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];// 打印異常,由于JS的異常信息是不會在OC中被直接打印的,所以我們在這里添加打印異常信息,self.context.exceptionHandler=^(JSContext *context, JSValue *exceptionValue){? ? context.exception= exceptionValue;NSLog(@"%@", exceptionValue);};}
三、實際操作中 JS call OC
先來看demo

JS Call OC
這個頁面整個都是通過HTML實現(xiàn)的,
1 計算階乘:在輸入框中輸入一個數(shù)字,然后在OC中計算出結(jié)果,最后顯示在HTML的頁面上;
2 測試log:點擊后,在后臺打印測試數(shù)據(jù);
3 OC原生Alert :點擊后,彈出OC的提示框;
4 addSubView:點擊后,在OC中添加一個View;
5 push to second ViewController :跳轉(zhuǎn)到下一個界面
總結(jié):以上功能都是在OC獲取HTML中按鈕的點擊事件,在后在OC中實現(xiàn)功能
??如何獲取HTML中的點擊事件呢??
在HTML中,為一個元素添加點擊時間有兩種寫法
或者
如果是第一種方法,
那么就要用JSExport協(xié)議關(guān)聯(lián)native的方法,要在webView的delegate里面添加
// 以 JSExport 協(xié)議關(guān)聯(lián) native 的方法self.content[@"native"] =self;
添加完之后,要聲明一個繼承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中實現(xiàn)這些方法,這樣就完成了!
如果是第二章方法,則只需要通過block的形式關(guān)聯(lián)JavaScript function就可以了!
self.context[@"log"] = ^(NSString*str){NSLog(@"%@", str);};
三、OC調(diào)用JS

OC調(diào)用JS
在這個例子中,界面的所有View都是OC創(chuàng)建的,點擊“交給JS處理計算階乘”后,將textfild的數(shù)據(jù)傳給JS,JS計算完成后在返回來!
這里面首先要獲取JS里面的計算函數(shù),在OC中,所有表示JS中對象,都用JSValue來創(chuàng)建,通過objectForKeyedSubscript方法或者直接使用下標(biāo)的方法獲取JS對象,然后使用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)建對象
......
零碎的補(bǔ)充1:對于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文件中,實現(xiàn)myFunc方法-(void) myFunc:(JSValue*)value{NSString * text = [valuevalueForProperty:@"text"];//打印"這里是文字"JSValue * func =? [valuevalueForProperty:@"callbackFun"];//這里是JS參數(shù)中的func;//調(diào)用這個函數(shù)[func callWithArguments:@[@"這里是參數(shù)"]];}
原文鏈接:http://m.itdecent.cn/p/cdaf9bc3d65d
著作權(quán)歸作者所有,轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),并標(biāo)注“簡書作者”。