JavaScriptCore 初探

經過前兩天的 JavaScript 的粗略學習,來看看 JavaScriptCore 。

JavaScriptCore 是封裝了JavaScript和Objective-C橋接的Objective-C API,只要用很少的代碼,就可以做到JavaScript調用Objective-C,或者Objective-C調用JavaScript。

  • OC 調用 JS
    // JScript
    NSString *path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"js"];
    NSString *javaScript = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
    // JSContext 初始化
    JSContext *context = [[JSContext alloc] init];
    // 獲取
    [context evaluateScript:javaScript];
    // 調用 
    JSValue *function = [context objectForKeyedSubscript:@"testAction"];
    // test result
    JSValue *result = [function callWithArguments:@[@5]];
    NSLog(@"result == %@",result); // ==> 15

test.js

var testAction = function(n) {
    if (n < 1) return;
    if (n === 1) return 1;
    return n + testAction(n - 1);
};
  • JS 調用 OC
    UIWebView UIWebViewDelegate
  - (void)webViewDidFinishLoad:(UIWebView *)webView {
    // 通過UIWebView獲得網頁中的JavaScript執行環境
    JSContext *context = [webView valueForKeyPath:
                          @"documentView.webView.mainFrame.javaScriptContext"];
    // 設置處理異常的block回調
    [context setExceptionHandler:^(JSContext *context, JSValue *exception) {
        NSLog(@"error: %@", exception);
    }];
    // 以 block 形式關聯 JavaScript function
    __weak typeof(self) weakSelf = self;
    context[@"alert"] = ^(NSString *str) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Test" message:nil preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *ensureAction = [UIAlertAction actionWithTitle:@"Ensure" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            NSLog(@"Test Ensure");
        }];
        [alertController addAction:ensureAction];
        dispatch_async(dispatch_get_main_queue(), ^{
            [strongSelf presentViewController:alertController animated:YES completion:nil];
        });
    };
}

WKWebView 不支持JavaScriptCore的方式但提供message handler的方式為JavaScript 與Objective-C 通信

 - (void)userContentController:(WKUserContentController *)userContentController
      didReceiveScriptMessage:(WKScriptMessage *)message;

當然得增加此方法的

WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
config.userContentController = [[WKUserContentController alloc] init];
 WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config];
[config.userContentController addScriptMessageHandler:self name:@"nativeCustomName"];
// 在用完后記得移除
// [config.userContentController removeScriptMessageHandlerForName:@"nativeCustomName"];

此處再來從 網上對 JavaScriptCore 了解 下 JavaScriptCore 的基本知識點:

  • JSValue: 代表一個JavaScript實體,一個JSValue可以表示很多JavaScript 原始類型例如 boolean, integers, doubles,甚至包括對象和函數。
  • JSManagedValue: 本質上是一個JSValue,但是可以處理內存管理中的一些特殊情形,它能幫助引用技術和垃圾回收這兩種內存管理機制之間進行正確的轉換。
  • JSContext: 代表JavaScript的運行環境,你需要用JSContext來執行JavaScript代碼。所有的JSValue都是捆綁在一個JSContext上的。
  • JSExport: 這是一個協議,可以用這個協議來將原生對象導出給JavaScript,這樣原生對象的屬性或方法就成為了JavaScript的屬性或方法,非常神奇。
  • JSVirtualMachine: 代表一個對象空間,擁有自己的堆結構和垃圾回收機制。大部分情況下不需要和它直接交互,除非要處理一些特殊的多線程或者內存管理問題。

JSValue

JSValue是我們需要處理的主要數據類型:它可以表示任何可能的Javascript值。一個JSValue被綁定到其存活的JSContext對象中。任何來源于上下文對象的值都是JSValue類型。

[JSValue form Nshipster ](http://nshipster.cn/javascriptcore/)

JSContext

JavaScript 執行的環境,同時也通過 JSVirtualMachine 管理著所有對象的生命周期,每個JSValue都和JSContext相關聯并且強引用context。

- (JSValue *)evaluateScript:(NSString *)script;
- (JSValue *)objectForKeyedSubscript:(id)key;
//以 block 形式關聯 JavaScript function
self.context[@"log"] = ^(NSString *str) {
        NSLog(@"%@", str);
};

下面這個例子,很好的解釋了上面兩個方法,以及對 JSValue 的一個大致了解

NSString *jsString = @"function test(a,b) {return a+b}";
[self.context evaluateScript:jsString];
JSValue *testValue = [self.context[@"test"] callWithArguments:@[@5, @1]];
NSLog(@"testValue===%@", [testValue toString]); // 6

JSExport

例如 JS 調用 OC 中的方法的時候,很方便也很熟悉,代理的感覺。

#define JSExportAs(PropertyName, Selector) \
    @optional Selector __JS_EXPORT_AS__##PropertyName:(id)argument; @required Selector

和我們平常使用 Delegate 一樣,先定義 protocol ,然后一一對應就好啦

@protocol TestJSExport <JSExport>
/**
 *  testAction JS 中的方法名
 *  void       OC 中的實現方法
 */
JSExportAs (testAction, - (void)testAction);
@end
self.context[@"app"] = self; // 以 JSExport 協議關聯 native 的方法
- (void)testAction {
    NSLog(@" JS Call Oc Action");
}

// JS 中的Button 的實現

<input type="button" value="testAction" onclick="app.testAction();" />

暫時記錄到此,接下來就是真正的實戰啦。

備注參考:

http://nshipster.cn/javascriptcore/
https://hjgitbook.gitbooks.io/ios/content/04-technical-research/04-javascriptcore-note.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,321評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,559評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,442評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,835評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,581評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,922評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,931評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,096評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,639評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,374評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,591評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,104評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,789評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,196評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,524評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,322評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,554評論 2 379

推薦閱讀更多精彩內容

  • 原:https://github.com/YanlongMa/SwiftJavaScriptCore 注:Java...
    Tippi閱讀 373評論 0 1
  • 隨著H5技術的興起,在iOS開發過程中,難免會遇到原生應用需要和H5頁面交互的問題。其中會涉及方法調用及參數傳值等...
    Chris_js閱讀 3,109評論 1 8
  • OC與JS交互之JavaScriptCore 本文摘抄自:https://hjgitbook.gitbooks.i...
    大沖哥閱讀 1,028評論 0 1
  • 本博客主要分以下幾個方面來介紹iOS中的JavaScriptCore JavaScriptCore簡介 JavaS...
    dullgrass閱讀 4,290評論 1 38
  • 本文由我們團隊的 糾結倫 童鞋撰寫。 寫在前面 本篇文章是對我一次組內分享的整理,大部分圖片都是直接從keynot...
    知識小集閱讀 15,278評論 11 172