乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      利用 JavaScriptCore 讓 Web 與 Native 交互更便捷

       jerry_tom123 2016-01-15

      還記得以前在網(wǎng)頁上用 iframe 指定一個 URL 并通過 native 的 - webView:shouldStartLoadWithRequest:navigationType: 回調(diào)方法攔截請求,再蛋疼的各種截取和判斷字符串,結(jié)合 json 結(jié)構(gòu)的字符串來獲取 web 端發(fā)來的數(shù)據(jù)。
      通過 - stringByEvaluatingJavaScriptFromString: 來拼接老長的字符串來傳遞數(shù)據(jù)給 web 端嗎。。。

      現(xiàn)在我們可以對這種方式說 「愛過~」 了。

      先看一下 Objective-C 與 JavaScript 之間類型的對應(yīng)關(guān)系

      Objective-C type JavaScript type
      nil undefined
      NSNull null
      NSString string
      NSNumber number, boolean
      NSDictionary Object object
      NSArray Array object
      NSDate Date object
      NSBlock Function object
      id Wrapper object
      Class Constructor object

      返回的 JSValue 轉(zhuǎn)換為 Objective-C 類型的方法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      
      - (BOOL)toBool;
      
      - (double)toDouble;
      
      - (int32_t)toInt32;
      
      - (uint32_t)toUInt32;
      
      - (NSNumber *)toNumber;
      
      - (NSString *)toString;
      
      - (NSDate *)toDate;
      
      - (NSArray *)toArray;
      
      - (NSDictionary *)toDictionary;
      
      - (id)toObject;
      
      - (id)toObjectOfClass:(Class)expectedClass;
      

      我們主要使用的是 JSContext 這個類,下面通過幾個簡單的例子來演示。

      首先需要加入 JavaScriptCore.framework 并引入。

      1
      
      #import <JavaScriptCore/JavaScriptCore.h>
      

      Objective-C 調(diào)用純 JavaScript

      例如有一段計算階乘的腳本

      test.js
      1
      2
      3
      4
      5
      6
      7
      8
      9
      
      function factorial(n) {
        if (n < 0){
            return;
        }
        if (n === 0){
            return 1;
        }
        return n * factorial(n - 1)
      };
      

      將腳本文件拖入項目。

      注意在項目的 TARGETS > Build Phases 中,把 *.js 文件從 Compile Sources 都拖到 Copy Bundle Resources,否則會有編譯警告。

      通過 - evaluateScript: 方法把腳本引入 JSContext 對象

      1
      2
      3
      4
      5
      6
      
      NSString *path = [[[NSBundle mainBundle] bundlePath]  stringByAppendingPathComponent:@"test.js"];
      
      NSString *testScript = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
      
      self.context = [[JSContext alloc] init];
      [self.context evaluateScript:testScript];
      

      通過 - objectForKeyedSubscript: 傳入 function 的名稱以取到該方法, 再通過 - callWithArguments: 傳入?yún)?shù)并得到返回值(如果有)。

      1
      2
      3
      4
      5
      6
      
      NSNumber *inputNumber = [NSNumber numberWithInteger:[self.inputNumberTextField.text integerValue]];
      
      JSValue *function = [self.context objectForKeyedSubscript:@"factorial"];
      JSValue *result = [function callWithArguments:@[inputNumber]];
      
      NSNumber *number = [result toNumber];
      

      JavaScript 調(diào)用 native 代碼

      • JSExport

      首先通過一個協(xié)議來關(guān)聯(lián) JavaScript 的 function 和 native 方法,

      還可通過 JSExportAs(functionName, Selector); 來指定 function 的別名。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      
      @protocol TestJSExport <JSExport>
      
      JSExportAs
      (functionNameForJS /** JavaScript function 的別名 */,
      
      - (void)handleFactorialCalculateWithNumber:(NSNumber *)number
      
      );
      
      - (void)pushToNextViewControllerWithTitle:(NSString *)title;
      
      @end
      

      然后在 UIWebView 回調(diào)方法 - webViewDidFinishLoad: 中把 web 的 javaScriptContext 與我們用來操作的 JSContext 對象關(guān)聯(lián),并把 self 設(shè)為 JavaScript 調(diào)用 function 的對象。

      1
      2
      3
      4
      5
      
      self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
      
      // 以 JSExport 協(xié)議關(guān)聯(lián) native 的方法
      self.context[@"native"] = self;
      //此處有誤,關(guān)聯(lián)到 self 會造成 self 這個對象無法釋放的問題,建議使用后面的 block 形式,或者關(guān)聯(lián)到非 self 本身的對象。(weakSelf 也不行)
      

      這樣在 web 中我們就可以通過所注冊的 native 對象來調(diào)用到 native 方法。

      1
      2
      3
      4
      5
      6
      7
      
      <textarea  id="input" style="font-size:10pt;color:black;"></textarea>
      
      <input type="button" value="計算階乘" onclick="native.functionNameForJS(input.value);" />
      
      <a id="push" href="#" onclick="native.pushToNextViewControllerWithTitle('Next VC');">
          push to next ViewController
      </a>
      

      建議使用后面的 block 形式,或者關(guān)聯(lián)到非 self 本身的對象。(weakSelf 也不行)

      • Block

      同樣的,先關(guān)聯(lián) javaScriptContext ,然后直接給 JSContext 對象 - setObject:forKeyedSubscript: 來設(shè)定相應(yīng) block。

      1
      2
      3
      4
      5
      
      self.context[@"log"] =
      ^(NSString *str)
      {
          NSLog(@"%@", str);
      };
      

      這樣在 web 中我們就可以直接調(diào)用上面注冊的 function

      1
      
      <input type="button" value="測試log" onclick="log('測試');" />
      

      使用 Block 要注意避免循環(huán)引用

      • 捕獲異常

      JSContextexceptionHandler 屬性賦予相應(yīng) Block

      1
      2
      3
      4
      5
      6
      
      self.context.exceptionHandler =
      ^(JSContext *context, JSValue *exceptionValue)
      {
          context.exception = exceptionValue;
          NSLog(@"%@", exceptionValue);
      };
      

      我們可以來利用一些開源的 JavaScript 庫來做一些比 native 代碼更方便和易于實現(xiàn)的東西

      隨便找了一個 Highcharts 圖表庫來做例子。

      注意:Highcharts 開源但不完全免費。個人用戶及非商業(yè)用途免費,商業(yè)用途需要購買許可。

      大致的調(diào)用代碼如下

      1
      2
      3
      4
      5
      6
      7
      8
      9
      
      NSArray *the1024Data = @[@33, @41, @32, @51, @42, @103, @136];
      NSDictionary *the1024Dict = @{@"name": @"1024", @"data": the1024Data};
      
      NSArray *theCCAVData = @[@8, @11, @21, @13, @20, @52, @43];
      NSDictionary *theCCAVDict = @{@"name": @"CCAV", @"data": theCCAVData};
      
      NSArray *seriesArray = @[the1024Dict, theCCAVDict];
      
      [self.context[@"drawChart"] callWithArguments:@[seriesArray]];
      
      1
      2
      3
      4
      
      function drawChart (seriesArray)
      {
        ...
      }
      

      詳細(xì)的代碼就不貼了,見項目 JavaScriptCoreSample 。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多