一:前言
? ? ? 有于本人對(duì)html,web網(wǎng)頁制作比較感興趣,所以身為ios程序員的我不務(wù)正業(yè)的看起了js,css,html,jq等的相關(guān)信息欲低,發(fā)現(xiàn)了一片新大陸啊坚洽,可惜本人學(xué)業(yè)不精只能學(xué)到一點(diǎn)皮毛爷肝。
由于最近web相關(guān)的都比較火嫉嘀,所以也開始研究了下ios與js的相關(guān)的一些通信交互炼邀,但是研究的比較淺,寫寫微博剪侮,這樣自己就也能記得住拭宁。
我的簡易的demo: https://github.com/taosiyu/TSYJavaScriptCoreDemo 請(qǐng)大家點(diǎn)個(gè)星星啊
二:關(guān)于javaScriptCore
? ? ? iOS7以后蘋果加入了JavaScriptCore.framework的框架。把 WebKit 的 JavaScript 引擎用 Objective-C 封裝瓣俯。讓Objective-C和JavaScript代碼的交互變得簡單方便杰标。至于ios7之前的方法框架由于現(xiàn)在ios7之前的機(jī)器較少而且利用截取方式調(diào)用感覺不怎么高大上,所以直接忽略彩匕,如果硬要了解請(qǐng)查看樓底的分享鏈接在旱。
? ? ? JSContext和JSValue
? ? ? ?JSVirtualMachine為JavaScript的運(yùn)行提供了底層資源,JSContext就為其提供著運(yùn)行環(huán)境推掸,通過- (JSValue *)evaluateScript:(NSString *)script;方法就可以執(zhí)行一段JavaScript腳本,并且如果其中有方法驻仅、變量等信息都會(huì)被存儲(chǔ)在其中以便在需要的時(shí)候使用谅畅。而JSContext的創(chuàng)建都是基于JSVirtualMachine:- (id)initWithVirtualMachine:(JSVirtualMachine *)virtualMachine;,如果是使用- (id)init;進(jìn)行初始化噪服,那么在其內(nèi)部會(huì)自動(dòng)創(chuàng)建一個(gè)新的JSVirtualMachine對(duì)象然后調(diào)用前邊的初始化方法毡泻。
JSValue則可以說是JavaScript和Object-C之間互換的橋梁,它提供了多種方法可以方便地把JavaScript數(shù)據(jù)類型轉(zhuǎn)換成Objective-C粘优,或者是轉(zhuǎn)換過去仇味。
JSContext 可以通過[webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];來獲取js環(huán)境
當(dāng)然在使用框架之前首先要導(dǎo)入頭文件
#import<JavaScriptCore/JavaScriptCore.h>
然后再載入html頁面
在頁面加載完成之后
- (void)webViewDidFinishLoad:(UIWebView *)webView{
//獲取js的環(huán)境阐污,在這里獲取是為了避免頁面沒有加載完成導(dǎo)致oc調(diào)不到 js的方法
self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
// 打印異常,由于JS的異常信息是不會(huì)在OC中被直接打印的,所以我們?cè)谶@里添加打印異常信息,
self.context.exceptionHandler =
^(JSContext *context, JSValue *exceptionValue)
? ? ?{
? ? ?context.exception = exceptionValue;
? ? ?NSLog(@"%@", exceptionValue);
? ? ?}
}
JS --------調(diào)用------>OC
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
// 以 html title 設(shè)置 導(dǎo)航欄 title
self.title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
// Undocumented access to UIWebView's JSContext
self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
// 打印異常
self.context.exceptionHandler =
^(JSContext *context, JSValue *exceptionValue)
{
context.exception = exceptionValue;
NSLog(@"%@", exceptionValue);
};
// 以 JSExport 協(xié)議關(guān)聯(lián) native 的方法
self.context[@"app"] = self;
// 以 block 形式關(guān)聯(lián) JavaScript function
self.context[@"log"] =
^(NSString *str)
{
NSLog(@"%@", str);
};
self.context[@"wowowowow"] =
^(NSString *str)
{
NSLog(@"============================>>>>>>>>>>>>>%@",str);
};
// 以 block 形式關(guān)聯(lián) JavaScript function
self.context[@"alert"] =
^(NSString *str)
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"msg from js" message:str delegate:nil cancelButtonTitle:@"ok" otherButtonTitles:nil, nil];
[alert show];
};
__block typeof(self) weakSelf = self;
self.context[@"addSubView"] =
^(NSString *viewname)
{
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(10, 500, weakSelf.view.frame.size.width, 100)];
view.backgroundColor = [UIColor redColor];
[weakSelf.view addSubview:view];
};
//多參數(shù)
self.context[@"mutiParams"] =
^(NSString *a,NSString *b,NSString *c)
{
NSLog(@"%@ %@ %@",a,b,c);
};
[self.context evaluateScript:@"var squareFunc = function(value) { return value * 2 }"];
JSValue *S = [self.context evaluateScript:@"squareFunc(10)"];
NSLog(@"tonumber = %@",S.toNumber);
}
主要是看看js調(diào)用oc的方法比以前用截取的方法方便很多年堆,也更符合mvc的思想,讓js和oc的關(guān)系更緊密.
其它的請(qǐng)自行查看代碼兢仰,說一堆廢話不如直接上代碼(其實(shí)是樓主懶)嬉愧。