一、說明
這篇文章記錄自己在研究OC與JS交互中的所得,以及遇到的問題與解決
由于蘋果的審核時間太漫長,一次審核不過,那又將進入另一個漫長的審核期。為了能在開發中方便更新,公司要求在項目中使用HTML5,這樣就涉及到OC與JS的交互, 在經過一段時間的摸索之后,將自己的研究記錄下來,以做備忘。
OC與JS的交互實現方式有很多,之前用的比較多的是WebViewJavaScriptBridge,但在IOS7之后,蘋果將JavaScriptCore框架開放。因此,這篇文章不講理論,主要講的是JavaScriptCore的實際使用。
文中所用的項目JavaScriptCoreDemo
廢話說完了,下面進入正題
二、Demo項目中功能介紹
Demo首頁
這個demo主要分為了三個部分來:
1.JS Call OC? , JS調用OC的函數
2.OC Call JS? , OC調用JS的函數
3.一個繪圖的例子
在做OC與JS交互工作之前,我們需要做些準備工作
1.導入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創建一個使用JS的環境,所以這里,我們先將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實現的,
1 計算階乘:在輸入框中輸入一個數字,然后在OC中計算出結果,最后顯示在HTML的頁面上;
2 測試log:點擊后,在后臺打印測試數據;
3 OC原生Alert :點擊后,彈出OC的提示框;
4 addSubView:點擊后,在OC中添加一個View;
5 push to second ViewController :跳轉到下一個界面
總結:以上功能都是在OC獲取HTML中按鈕的點擊事件,在后在OC中實現功能
??如何獲取HTML中的點擊事件呢??
在HTML中,為一個元素添加點擊時間有兩種寫法
或者
如果是第一種方法,
那么就要用JSExport協議關聯native的方法,要在webView的delegate里面添加
// 以 JSExport 協議關聯 native 的方法self.content[@"native"] =self;
添加完之后,要聲明一個繼承JSExport的協議,協議中聲明供JS使用的OC的方法
@protocolTestJSExportJSExportAs(calculateForJS/** handleFactorialCalculateWithNumber 作為js方法的別名 */, - (void)handleFactorialCalculateWithNumber:(NSNumber*)number );- (void)pushViewController:(NSString*)view title:(NSString*)title;-(void)log:(NSString*)l;@end
在OC中實現這些方法,這樣就完成了!
如果是第二章方法,則只需要通過block的形式關聯JavaScript function就可以了!
self.context[@"log"] = ^(NSString*str){NSLog(@"%@", str);};
三、OC調用JS
OC調用JS
在這個例子中,界面的所有View都是OC創建的,點擊“交給JS處理計算階乘”后,將textfild的數據傳給JS,JS計算完成后在返回來!
這里面首先要獲取JS里面的計算函數,在OC中,所有表示JS中對象,都用JSValue來創建,通過objectForKeyedSubscript方法或者直接使用下標的方法獲取JS對象,然后使用callWithArguments方法來執行函數
// 方法一.? JSValue *function = [self.context objectForKeyedSubscript:@"factorial"];// 方法二.JSValue * function =self.context[@"factorial"];JSValue *result = [function callWithArguments:@[inputNumber]];self.showLable.text= [NSStringstringWithFormat:@"%@", [result toNumber]];
四、demo之外(慢慢在總結)
1.JS注入
2.在OC中為JS創建對象
......
零碎的補充1:對于JS 函數中,參數中有函數的,在OC中用JSValue接收
// 比如:JS代碼functionmyFunc({"text":"這里是文字","callbackFun":function(string){alert'string'}});//OC代碼中在.h的protocol中聲明JS要調用的OC方法//.h protocol中,函數名稱要和JS中相同,這里接收的參數為JSValueJSExportAs(myFunc, -(void) myFunc:(JSValue*)value);//在.m文件中,實現myFunc方法-(void) myFunc:(JSValue*)value{NSString * text = [valuevalueForProperty:@"text"];//打印"這里是文字"JSValue * func =? [valuevalueForProperty:@"callbackFun"];//這里是JS參數中的func;//調用這個函數[func callWithArguments:@[@"這里是參數"]];}
原文鏈接:http://www.lxweimin.com/p/cdaf9bc3d65d
著作權歸作者所有,轉載請聯系作者獲得授權,并標注“簡書作者”。