iOS 基礎(chǔ)--JavaScriptCore簡(jiǎn)單總結(jié)

<big><b>紅酥手墅冷,黃藤酒谆刨,滿城春色宮墻柳橘霎!</b></big><伊布>

  • 蘋果在 iOS7中增加了 JavaScriptCore 框架,而這個(gè)框架正是大大的簡(jiǎn)化 JavaScript 與 Objective-C之間的交互韧掩!它把 WebKit 的 JavaScript 引擎用 Objective-C 封裝,我們可以用很簡(jiǎn)便的方法快速的接入當(dāng)下流行的 JavaScript蔫饰。
  • JavaScriptCore可以讓我們?cè)?OC 執(zhí)行的代碼的任何地方運(yùn)行JS 代碼,不依賴 WebView
  • JavaScriptCore主要就是給我們提供了 JS 代碼的執(zhí)行環(huán)境并進(jìn)行解析運(yùn)行
  • 讓我們應(yīng)用擴(kuò)展性大大提高愉豺,提供了動(dòng)態(tài)去修改我們局部代碼或者邏輯的思路(實(shí)現(xiàn)熱更新)篓吁,同時(shí)讓我們?nèi)デ度刖W(wǎng)頁(yè)并加以調(diào)整變得輕松。

簡(jiǎn)單的總結(jié)一下關(guān)于這個(gè)框架基礎(chǔ)使用蚪拦,才淺學(xué)薄欠缺之處望包含指正杖剪!

  • JSContext

它是 JavaScript 代碼的運(yùn)行環(huán)境,也就是作用的范圍驰贷。每一個(gè) JSContext 就是一個(gè)全局的環(huán)境變量盛嘿!我們創(chuàng)建一個(gè) JSContext 對(duì)象之后,可以利用它去執(zhí)行相應(yīng)的JavaScript 的代碼操作(創(chuàng)建變量括袒,定義方法等)次兆!

  • JSValue

它是為了處理 Objective-C 對(duì)象(強(qiáng)類型)和 JavaScript 對(duì)象(弱類型)差異的類,實(shí)現(xiàn) OC 和 JS 對(duì)象的相互轉(zhuǎn)化锹锰。在處理的時(shí)候 JSValue對(duì)象包裹著來(lái)自 JSContext 的值例如字符串芥炭、對(duì)象甚至是方法、還有一些錯(cuò)誤的特殊的 JS 值類似 null 和 undefined恃慧。這個(gè)類的一些列方法(得到 Foundation 框架下得類型)就是為了我們?cè)?OC 訪問這些值時(shí)候能夠正常的去訪問處理园蝠!可以理解成是 JS 和 OC 之間互相轉(zhuǎn)換的橋梁,下圖是一個(gè)簡(jiǎn)單總結(jié)的表格痢士!

JS類型 JSValue轉(zhuǎn)OC Swift 類型 OC 類型 OC 轉(zhuǎn) JSValue
string toString String! NSString
boolean toBool Bool Bool valueWithBool:inContext:
number toNumberto
toDouble
toInt32
toUInt32
NSNumber!
Double
Int32
UInt32
NSNumber
double
int32_tuint32_t
valueWithDouble:inContext:
valueWithInt32:inContext:
valueWithUInt32:inContext:
Date toDate NSDate! NSDate
Arrar toArray [AnyObject]! NSArray valueWithNewArrayInContext:
Object toDictionary [NSObject : AnyObject]! NSDictionary valueWithNewObjectInContext:
Object toObject
toObjectOfClass:
custom type custom type( id類型) valueWithObject:inContext:
undefined nil nil valueWithUndefinedInContext
null NSNull NSNull valueWithNullInContext:

  • 我們通過代碼簡(jiǎn)單理解一下 OC 和 JS交互簡(jiǎn)單實(shí)現(xiàn)
  • 創(chuàng)建JSContext 對(duì)象
JSContext *context = [[JSContext alloc] init];```
 - 用這個(gè)對(duì)象執(zhí)行 JS 代碼得到一個(gè) JSValue 對(duì)象
```code
JSValue *jsValue = [context evaluateScript:@"23+6"];```
 - JSValue 值 轉(zhuǎn)換成 OC 的結(jié)果值
```code 
int ocValue =  [jsVlaue toInt32];```
 - 執(zhí)行JS函數(shù)(OC中的 Block)這樣就相當(dāng)于下 JS 中調(diào)用了 OC 代碼
```code
//  就是把這個(gè)方法賦給 JS 的 log 這個(gè)屬性(沒有的話JS 會(huì)自動(dòng)創(chuàng)建這個(gè)屬性)
  context[@"log"] = ^(NSInteger value){
        NSLog(@"-------->%ld",value);// 這里打印了摻入的第一個(gè)傳入的參數(shù)
        // 處理傳進(jìn)來(lái)的參數(shù)
        NSArray *arr = [JSContext currentArguments]; // 返回一個(gè)數(shù)組 獲取到的是 JS 傳進(jìn)去的不定參數(shù)
        for (id item in arr) {
            NSLog(@"--->%@",item);// 依次打印了傳進(jìn)來(lái)的參數(shù)
        }
    };
// 執(zhí)行 JS 代碼
    [context evaluateScript:@"log(11,2,3)"];```


![打印結(jié)果](http://upload-images.jianshu.io/upload_images/1523603-76924e82a8ecc542.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

 - 我們也可以在 OC 中使用 JS 代碼結(jié)果
  - 小例子:這里我寫一個(gè)求 1->n 和 以及 N 階乘 的 JS 代碼然后執(zhí)行結(jié)果轉(zhuǎn)成 OC 的
```code
 JSContext *context = [[JSContext alloc] init];
# 這里是 JS 求和以及計(jì)算階乘的代碼
 [context evaluateScript:@"var numSum = function(n){var sum = 0;  for( i = 0;i <= n;i++ ){ sum += i; } return sum };var factorial = function(n) { if (n < 0) return; if (n === 0) return 1; return n * factorial(n - 1) };"];
    JSValue *function = context[@"numSum"];
# 調(diào)用 JS 函數(shù)方法彪薛,并返回函數(shù)的結(jié)果 傳入的參數(shù)是一個(gè)給函數(shù)的傳遞的參數(shù)放到數(shù)組里面
    JSValue *numSum = [function callWithArguments:@[@5]];
    NSLog(@"把 JS結(jié)果轉(zhuǎn)化成 OC結(jié)果---->%d",[numSum toInt32]);```

![打印結(jié)果](http://upload-images.jianshu.io/upload_images/1523603-b0c193583da713ce.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
--------

-----
- 再寫一個(gè)簡(jiǎn)單的例子,我們?cè)诶?OC 的WebView 加載 一個(gè)網(wǎng)頁(yè)怠蹂,網(wǎng)頁(yè)上有一個(gè) Button善延,點(diǎn)擊這個(gè) Button 我們 iOS 客戶端相應(yīng)的進(jìn)行一些操作也就是 OC 和 HTML 交互!
 -  一個(gè)簡(jiǎn)單的 HTML 代碼
 ```code
 <!DOCTYPE html>
 <html>
    <head>
        <meta charset="UTF-8">
            <title></title>
            </head>
    <body>
        <input type="button" value="login" onclick="log()" />
    </body>
</html>
  • 我們用 WebView 加載這個(gè) HTML
UIWebView *webview = [[UIWebView alloc] initWithFrame:CGRectMake(10, 10, 300, 500)];// 創(chuàng)建
    [self.view addSubview:webview];// 添加父視圖
    webview.delegate = self;// 設(shè)置代理
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];// 找到要加載的 HTML 文件
    NSString *urlStr = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
    [webview loadHTMLString:urlStr baseURL:nil];// 加載``` 
 - 我們?cè)诖矸椒ㄖ蝎@取這次加載
```code
     // 每次加載網(wǎng)頁(yè)請(qǐng)求都會(huì)走該方法 
     - (void)webViewDidFinishLoad:(UIWebView *)webView
 {// 獲取當(dāng)期WebView 相關(guān)的 context城侧,獲取 JS執(zhí)行環(huán)境
JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
// 我們把點(diǎn)擊的事件獲取到 也就實(shí)現(xiàn)了效果
     context[@"log"] = ^(){
        NSLog(@"點(diǎn)擊了網(wǎng)頁(yè)上那個(gè)的 Button挚冤!")
}```

![結(jié)果打印.gif](http://upload-images.jianshu.io/upload_images/1523603-f3dfcdb6119cfa22.gif?imageMogr2/auto-orient/strip)

- JSExport
> 要想在 JS 中調(diào)用OC 對(duì)象的方法和屬性,需要把這些屬性方法放到繼承于 JSExport 的協(xié)議中赞庶,因?yàn)橹挥蠮SExport 協(xié)議中的方法才能被 JavaScript 識(shí)別!OC 對(duì)象相應(yīng)的實(shí)現(xiàn)協(xié)議方法澳骤!

 - 代碼示例我們先定義一個(gè)協(xié)議
```code
// 一定要繼承于 JSExport
@protocol JS_OC_Delegate <JSExport>
@property (nonatomic, strong) NSString *name;
@end```
   - 在一個(gè)類中(這里是在 ViewController)中遵循代理并實(shí)現(xiàn)方法
```code
@synthesize name;```
   - 轉(zhuǎn)化執(zhí)行
```code
  self.name = @"云之君兮鵬";
    JSContext *context = [[JSContext alloc] init];
    context[@"OC_Object"] = self;
    [context evaluateScript:@"OC_Object.name = '小超人'"];
     NSLog(@"%s--->%@",__func__,self.name);

打印結(jié)果

  • 注意一些問題:

  • 不要在Block 中直接引用使用外面的 JSContext 對(duì)象歧强,應(yīng)該用·[JSContext currentContext];

  • 同樣的不要直接在 Block 中調(diào)用外界的 JSValue 對(duì)象,需要的話可以利用參數(shù)傳遞進(jìn)去为肮。
    - 原因(我們?cè)?OC 中經(jīng)程幔回去注意的問題,避免了循環(huán)引用颊艳,相互持有茅特!Block 可以保有變量引用忘分,而且 JSContext 也強(qiáng)引用它所有的變量。)

  • 當(dāng)我們使用JS 調(diào)用 OC 的回調(diào)方法時(shí)白修,均是在子線程中執(zhí)行的妒峦,這樣的話我們得注意需要的時(shí)候,要回到主線程去更新我們 UI 界面兵睛。

JSContext *context = [[JSContext alloc] init];
    context[@"函數(shù)名"] = ^(類型 參數(shù)){
# 尷尬了 循環(huán)引用
JSValue *value =  [JSValue valueWithNewObjectInContext:context];
# 顧德樂 正常使用
JSValue *value =  [JSValue valueWithNewObjectInContext:[JSContext currentContext]];
    };

今天先到這了肯骇,日后補(bǔ)充更新,開心就好!對(duì)了簡(jiǎn)友們節(jié)日快樂!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末祖很,一起剝皮案震驚了整個(gè)濱河市笛丙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌假颇,老刑警劉巖胚鸯,帶你破解...
    沈念sama閱讀 222,464評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異笨鸡,居然都是意外死亡姜钳,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門镜豹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)傲须,“玉大人,你說(shuō)我怎么就攤上這事趟脂√┓恚” “怎么了?”我有些...
    開封第一講書人閱讀 169,078評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵昔期,是天一觀的道長(zhǎng)已卸。 經(jīng)常有香客問我,道長(zhǎng)硼一,這世上最難降的妖魔是什么累澡? 我笑而不...
    開封第一講書人閱讀 59,979評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮般贼,結(jié)果婚禮上愧哟,老公的妹妹穿的比我還像新娘。我一直安慰自己哼蛆,他們只是感情好蕊梧,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,001評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著腮介,像睡著了一般肥矢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上叠洗,一...
    開封第一講書人閱讀 52,584評(píng)論 1 312
  • 那天甘改,我揣著相機(jī)與錄音旅东,去河邊找鬼。 笑死十艾,一個(gè)胖子當(dāng)著我的面吹牛抵代,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播疟羹,決...
    沈念sama閱讀 41,085評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼主守,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了榄融?” 一聲冷哼從身側(cè)響起参淫,我...
    開封第一講書人閱讀 40,023評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎愧杯,沒想到半個(gè)月后涎才,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,555評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡力九,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,626評(píng)論 3 342
  • 正文 我和宋清朗相戀三年耍铜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片跌前。...
    茶點(diǎn)故事閱讀 40,769評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡棕兼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出抵乓,到底是詐尸還是另有隱情伴挚,我是刑警寧澤,帶...
    沈念sama閱讀 36,439評(píng)論 5 351
  • 正文 年R本政府宣布灾炭,位于F島的核電站茎芋,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蜈出。R本人自食惡果不足惜田弥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,115評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望铡原。 院中可真熱鬧偷厦,春花似錦、人聲如沸燕刻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)酌儒。三九已至,卻和暖如春枯途,著一層夾襖步出監(jiān)牢的瞬間忌怎,已是汗流浹背籍滴。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留榴啸,地道東北人孽惰。 一個(gè)月前我還...
    沈念sama閱讀 49,191評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像鸥印,于是被迫代替她去往敵國(guó)和親勋功。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,781評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 項(xiàng)目中涉及OC與網(wǎng)頁(yè)的交互库说,查找資料時(shí)看到了JavaScriptCore.framework狂鞋,就對(duì)照文章ios7 ...
    YaoYaoX閱讀 2,355評(píng)論 7 11
  • 本文由我們團(tuán)隊(duì)的 糾結(jié)倫 童鞋撰寫。 寫在前面 本篇文章是對(duì)我一次組內(nèi)分享的整理潜的,大部分圖片都是直接從keynot...
    知識(shí)小集閱讀 15,255評(píng)論 11 172
  • JavaScriptCore框架主要是用來(lái)實(shí)現(xiàn)iOS與H5的交互骚揍。由于現(xiàn)在混合編程越來(lái)越多,H5的相對(duì)講多啰挪,所以研...
    水靈芳蕥閱讀 1,413評(píng)論 1 8
  • 寫在前面 本篇文章是對(duì)我一次組內(nèi)分享的整理信不,大部分圖片都是直接從keynote上截圖下來(lái)的,本來(lái)有很多炫酷動(dòng)效的亡呵,...
    等開會(huì)閱讀 14,476評(píng)論 6 69
  • 注:本文copy自http://www.reibang.com/p/ac534f508fb0抽活,純屬當(dāng)筆記使用。 概...
    BookKeeping閱讀 732評(píng)論 1 3