1. 程式人生 > >iOS原生程式碼通過webView與js指令碼互動

iOS原生程式碼通過webView與js指令碼互動

  前段時間公司的一個專案需要使用的到OC程式碼與js指令碼的互動。對於入行不久的我,當時也是在部落格裡面爬文來解決。做下來之後把我自己通過實踐和學習得來的東西整理一下,以便在這方面接觸不多的人能夠快速的掌握OC與js的互動。新手教程,大神勿噴,如有錯誤,多多指教。  

 好了前言已足,直接來乾貨。

  開始。首先我們需要用到JavaScriptCore.framework庫,所以我們需要在工程裡面連結JavaScriptCore.framework庫,這個我就不再贅述。

  一、js指令碼調OC的方法,可以將js程式碼的值傳入OC,或者OC響應js程式碼的互動事件等等。

         1.首先我們需要建立一份OC與js互動的協議。

      #import <JavaScriptCore/JavaScriptCore.h>//首先匯入標頭檔案

      /**

       *  建立一個遵守了JSExport協議的協議

       */

      @protocolTestJSObjectProtocol<JSExport>

      /**

       * 通過js程式碼呼叫本方法,並且傳入頁面標題值,來修改當前頁面的title

       *

       *  @param pageTitle  js需要傳入的頁面標題

       */

      -(void

)setPageTitle:(NSString*)pageTitle;

      @end

         2.通過以上程式碼,我們擬定了一份互動協議,並且申明瞭一個方法,方法作用為通過js指令碼來修改我們的頁面標題。然後我們需要建立一個類來準守這份協議,並且實現它的方法。

      @interfaceWebViewBridgeTool :NSObject<TestJSObjectProtocol>

      @end

      @implementation WebViewBridgeTool

      //實現我們擬定的協議的方法

       #pragma mark - <TestJSObjectProtocol>

      /**

       * 我們在這裡實現協議裡面的方法

       *

       *  @param pageTitle pageTitlejs指令碼呼叫這個方法的時候傳入的值,我們拿到這個值之後,就可以想做什麼就做什麼了

       */   

      -(void)setPageTitle:(NSString *)pageTitle{

NSLog(@"我們想要設定的頁面標題為:%@",pageTitle);

      }

      @end


        3.到這一步,我們需要的東西已經具備了,剩下的就是如何在js程式碼裡面去呼叫setPageTitle這個方法了。接下來我們建立一個ViewController新增一個WebView來實現。

      #import "WebViewBridgeTool.h"//匯入標頭檔案

       @interfacePublicWebViewController :UIViewController

      @property(nonatomic,strong)WebViewBridgeTool * app;// 我們需要將這個物件傳入我們的js程式碼中

      @property(nonatomic,strong)UIWebView * webView;//

       @end

       @implementationPublicWebViewController

      -(void)viewDidLoad{

           [superviewDidLoad];

         //初始化需要寫入js程式碼的物件

           _app=[[WebViewBridgeToolalloc]init];

                //假設我們已經初始化好了webview,並且將webview的delegate設定為self

          [self.viewaddSubview:self.webView];

      }

      #pragma mark - <UIWebViewDelegate,UIScrollViewDelegate>

      /**

       * 這個方式是webview的代理方式,根據名字我們知道這個方法在webview開始載入介面的時候呼叫,我們在網頁開始載入的時候將我們的              * 互動物件通過JSContext寫入到我們的js腳本里面去

       *

       *  @param webView

       */

      -(void)webViewDidStartLoad:(UIWebView*)webView{

JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

context[@"app"]=self.app;

      }

//我在網頁載入完成的時候又寫入了一次

-(void)webViewDidFinishLoad:(UIWebView*)webView{

JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

context[@"app"]=self.app;

}

       4.通過以上操作,我們在webview載入網頁的時候,把app這個物件寫入了js指令碼中,我們的webview裡面載入的網頁上的js腳本里面就會有我們的app物件。在js腳本里面就可以通過app這個物件來呼叫我們oc的方法了。

         app.setPageTitle("新標題");//js裡面的程式碼

 值得注意的是:我們協議裡面的方法如果有多個引數,除了第一個引數,後面的引數不能有引數名字,需要省略引數名字,只有一個':',否則,js無法呼叫。因為引數的名字也是方法名字的一部分。

      -(void)showImageWithImageKeys:(NSString *)keyArrayJson :(NSInteger)index;//顯示一組圖片

      -(void)showImageWithImageKeys:(NSString *)keyArrayJson index:(NSInteger)index;//不能這樣寫,第二個引數不應該有名字

二、OC呼叫js的方法,這個就相對簡單。例如js裡面有一個commit方法,我們可以通過名字來匹配到這個方法。

      [self.webViewstringByEvaluatingJavaScriptFromString:[NSStringstringWithFormat:@"commit()"]];


         如果需要傳入引數,例如js裡面有一個求和函式sum(a,b),我們只需要通過字串拼接的方式將引數傳入即可。
      [self.webViewstringByEvaluatingJavaScriptFromString:[NSStringstringWithFormat:@"sum(%d,%d)",10,5]];
     以上就是簡單的OC與js互動的程式碼,雖然有成熟框架如WebViewJavascriptBridge,但是如果你只需要最簡單的互動,這種方式,也許會來的更快。