iOS開發-javaScript互動

林欣達發表於2016-07-05

前言

當前混合開發模式迎來了前所未有的發展,跨平臺開發、熱更新等優點決定了這種模式的重要地位。雖然前端介面在互動、動效等多方面距離原生應用還有差距,但毫無疑問混合開發只會被越來越多的公司接受。在iOS中,混合開發模式被分為兩個時代,分別是iOS7之前的坑爹時代與之後的黃金時代,其分割代表為JavaScriptCore框架

iOS開發-javaScript互動

坑爹時代

作為完美避開iOS7之前版本的幸運兒,我只能從某位前輩的口中得知那悲慘的歲月。作為那個年代唯一能與前端介面互動的手段就是UIWebView,先不說它自身的記憶體洩露缺陷,下面是一段前輩寫過的程式碼:

在那個年代,前輩的小夥伴們把前端事件的觸發條件設定為連結跳轉,然後通過連結中的關鍵字元來判斷處理操作。為此,需要定義好些個資料集合來儲存這些關鍵字元的處理操作。如果遇到應用和前端交換互動資料的時候,那一長串的引數字元全部拼接在請求地址裡,想想也是醉了。另外的互動方法就是通過stringByEvaluatingJavaScriptFromString方法來執行js程式碼。

JavaScriptCore

JavaScriptCore是一套用來對JS程式碼進行解析和提供執行環境的開源框架,極大的簡化了我們的互動過程。下面從專案和JS程式碼相互呼叫的兩個不同操作介紹其中相對應的方法

專案呼叫JS程式碼

  • JSContext
    一個JSContext物件是JavaScript執行的全域性環境物件,它提供了程式碼執行和註冊方法介面的服務。下面的程式碼就建立了一個JSContext物件,並且定義了一部分的JS程式碼加入到執行環境中

    此外,在JS程式碼執行過程中,可能會出現語法錯誤等多種錯誤,通過下面的程式碼可以對這些錯誤進行處理
  • JSValue
    JSValue是所有JSContext操作後返回的值,包裝了幾乎所有的資料型別,包括錯誤和IMP指標等。在JSValue類結構中存在多個toXXXX命名的方法轉換成iOS資料型別以及call方法來呼叫方法。下面的程式碼從JSContext環境中獲取已存在的部分變數,並且執行建立一個儲存person資訊的字典

通過上面的例子,我們可以看到,只要瞭解到JS程式碼中我們需要呼叫的方法資訊,通過JSContext + JSValue的方式我們就能輕鬆的在專案中呼叫前端介面的方法,而不再需要拼接長串引數字元通過連結地址傳遞給前端介面

JS呼叫專案程式碼

JavaScript訪問我們程式碼中的物件以及方法有兩種方式:BlocksJSExport

  • Blocks
    自定義的block程式碼可以通過JSContext轉換成JS程式碼中的函式指標呼叫,這裡存在一個坑就是Swift中的閉包無法完成這樣的型別轉換,因此這種方式的操作流程在Swift中是這樣的:Closure -> block -> function pointer。在閉包轉成block的這一過程中,需要使用一個重要的關鍵符@convention

    這時候,只要前端在JS的按鈕點選程式碼中呼叫convertFunc()這句程式碼就會執行這個closure中的程式碼。使用這種方式要注意由於閉包的捕獲特性,有可能會導致你的JSContext物件被引用而無法被釋放,使用JSContext.current()獲取當前上下文來解決引用問題
  • JSExport
    JS中呼叫iOS方法的時候,通過呼叫JSExport的派生協議方法來實現。所有派生協議的方法會自動提供給JavaScript程式碼使用,這個在下面的demo中可以看到

實戰

在本文demo中我寫了一段JS程式碼,下面放出這段程式碼以及執行效果。其中要注意的是按鈕的onclik表示按鈕點選的響應事件:

iOS開發-javaScript互動

首先我們需要載入這個HTML檔案,然後獲取程式碼執行的全域性環境物件。基本上在所有的HTML格式檔案中,獲取環境物件的keyPath都是一樣的:

對照HTML程式碼,最上面的按鈕點選之後會呼叫一個sindrilin.call()的方法,這個方法最終要由我們的控制器來進行處理。我們可以把這個字串分成類似Target-Action機制的兩部分,前者sindrilin表示響應者,後面call()表示響應事件。其中Target的設定方式如下

響應者已經有了,那麼響應事件也要我們實現程式碼,這裡就需要用到JSExport協議了。所有這種類似Target-Action的事件觸發都會通過這個協議獲取方法實現,因此我們需要自定義響應協議以及響應事件。對於有引數的方法我們需要用@objc(name)的方式給方法起OC式的方法名,才能保證能被正確呼叫響應:

使用者在前端介面輸入賬戶和密碼資訊之後點選登入就會呼叫login(accountInfo: String)方法,將使用者名稱和密碼拼湊成JSON字串傳遞過來。在響應方法中我解析獲取對應欄位的使用者資訊,並且組轉成新的字串呼叫JS的彈窗函式彈出響應。demo下載

iOS開發-javaScript互動

相關文章