本文細緻探討了 Xcode(以 iOS 裝置為目標)中的 PhoneGap(也稱為 Apache Cordova)應用程式本機外掛程式。如果您剛開始接觸 PhoneGap 或者需要回顧 PhoneGap 基礎知識,請先閱讀 Xcode for iOS 的 PhoneGap 入門,然後再繼續閱讀本文。
本文交替使用術語 Cordova 和 PhoneGap 指示同一開源應用程式平台,該平台可供您使用 HTML 和 JavaScript 建立本機安裝的行動裝置 App程式。PhoneGap 程式碼程式庫已遷移至 Apache 軟體基金會的開放資源中,名為 Cordova。Adobe 則仍以 PhoneGap 名稱進行分發。有關更多資訊,請參閱 Brian Leroux 發布的部落格文章“PhoneGap、Cordova、名稱有什麼關係?”正如 Brian 在這篇文章中所說,“目前唯一的區別在於下載包名稱的不同,並且這種情況仍將維持一段時間。
PhoneGap 不僅可讓您利用 Web 技術為本機安裝的行動裝置 App程式構建使用者介面,還能提供基於 JavaScript 的 API 供您與本機裝置功能進行互動。預設情況下,PhoneGap 可訪問裝置網路攝影機、加速計、檔案系統、GPS 位置及其他功能間的媒體重放。但是,PhoneGap 並未揭示供您在 JavaScript 應用程式內使用的每一個本機 API。如果您希望 PhoneGap 執行其預設功能集以外的操作,可以使用 PhoneGap 本機外掛程式模型擴充核心 PhoneGap API 的功能。
PhoneGap 本機外掛程式與案頭瀏覽器的外掛程式不同;它們為您提供了一種外掛程式自訂代碼以增加 PhoneGap 應用程式架構功能的方式。PhoneGap 本機外掛程式可讓您以機器碼的形式建立全新的自訂功能,並通過 PhoneGap 的本機-JavaScript 橋將其顯示給 PhoneGap 應用程式。這意味著,您可以顯示所有本機庫或架構,以便在基於 JavaScript 的 PhoneGap 應用程式內部使用。
瞭解 PhoneGap 本機外掛程式的結構
在您開始編寫 PhoneGap 本機外掛程式之前,瞭解 PhoneGap 應用程式容器如何向基於 JavaScript 的應用程式顯示本機作業系統功能將會有所協助。
所有 Cordova API 均包含以下兩個有關組件:一個可以在您的應用程式內部進行訪問的基於 JavaScript 的介面,以及用於以機器碼執行操作的對應本機類。通常情況下,JavaScript 類和本機類具有相互鏡像的 API,這樣就能輕鬆地進行跟蹤。JavaScript 類使用 Cordova.exec()
函數調用機器碼。當它調用 Cordova.exec
時,可將其傳遞至結果處理常式函數和錯誤處理程式函數,同時還會將一組參數傳遞至機器碼,並將引用傳遞至本機類名稱和本機函數名稱。Cordova 將負責管理 JavaScript 與本機之間的通訊,您可以專心構建自己的應用程式。
要瞭解有關 PhoneGap 本機外掛程式的更多資訊,請登入 Cordova wiki 查看該核心 API 的原始碼。整個 PhoneGap 架構均構建於同一模式之上,您可以在這裡瞭解這一模式。
構建首個外掛程式
要開始構建您的首個 PhoneGap 外掛程式,您需要按照 Xcode for iOS 的 PhoneGap 入門一文中所述的步驟建立一個新 PhoneGap 項目。我將自己的項目命名為 MyFirstPhoneGapNativePlugin。
JavaScript 類
在您設定完 Hello Xcode 項目後, 即可準備為本機外掛程式建立 JavaScript 介面。您需要使用函數(將要鏡像通過機器碼顯示的邏輯)建立類。在 www 檔案夾下,建立一個名為 HelloPlugin.js 的 JavaScript 檔案,其中包含如下所示的簡單 JavaScript 類。
var HelloPlugin = { callNativeFunction: function (success, fail, resultType) { return Cordova.exec( success, fail, "com.tricedesigns.HelloPlugin", "nativeFunction", [resultType]); } };
HelloPlugin 類包含一個名為 callNativeFunction
的函數,它接收了一個成功回呼函數、一個錯誤回呼函數和一個 resultType
字串參數。callNativeFunction
函數包含 Cordova.exec
函數,因而將會調用實際機器碼。此類中沒有其他 JavaScript,但您可以根據自身需要在此處添加 JavaScript 代碼。
調用 Cordova.exec
後,將會看到以下五個參數:
- 一個成功回呼函數(機器碼層成功響應時調用的函數)引用
- 一個錯誤回呼函數(機器碼層錯誤響應時調用的函數)
- 一個機器碼類字串引用(我將會在下文進行詳細介紹)
- 一個應當調用的函數名稱字串引用
- 一個將要傳遞至機器碼的參數數組
請記住,JavaScript 和機器碼層之間的代碼執行操作並不同步,因此,在開發 PhoneGap 本機外掛程式時需要使用回呼函數和非同步編碼實踐。
本機類
要建立機器碼層,請首先建立一個新的本機 Objective-C 類,它擴充核心 Cordova API 的 CDVPlugin 類:
圖 1. 建立新檔案。
- 在 New File 嚮導中,選擇 Objective-C 類模板,然後單擊 Next(參見圖 2)。
圖 2. 選擇 Object-C class 模板。
- 鍵入 HelloPlugin 作為新類的名稱,並將該類納為 CDVPlugin 的子類(參見圖 3)。
圖 3. 命名該類。
CDVPlugin 類是所有 Cordova 類均必須擴充的父類。CDVPlugin 類通過 PhoneGAP API 封裝本機 JavaScript 通訊所需的所有必要邏輯。PhoneGap.exec
函數可讓您調用該新類上的函數。CDVPlugin 類包含一個名為 writeJavascript
的核心函數,可讓您調用 PhoneGap 應用程式 Web 視圖內的 JavaScript。本機到 Web JavaScript 這一方向的所有通訊均必須使用 writeJavascript
函數完成。
- 單擊 Next。
- 出現提示後,為新檔案指定位置(最好指定在 Xcode 項目內的 Plugins 目錄下),然後單擊 Finish 繼續操作。
您將會在 PhoneGap 項目內看到一個新的標頭檔 (.h) 和一個新的實現檔案 (.m)(參見圖 4)。
圖 4. 新的本機類檔案。
- 接下來,在您的 .h 檔案中為
nativeFunction
函數添加定義;例如:
#import <Cordova/CDV.h> @interface HelloPlugin : CDVPlugin - (void) nativeFunction:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options; @end
此定義包含以下兩個參數:一個是 NSMutableArray
,其中包含從 JavaScript 層和選項字典(地圖)接收到的參數。在本例中,您只需要關注參數數組。標頭檔只包含方法簽名;您無需在 .h 檔案中包含任何應用程式邏輯。
- 在您建立類簽名後,將邏輯添加到 .m 檔案的
nativeFunction
函數執行個體中。您將在下面看到此本機外掛程式類內部使用的 Objective-C 函數樣本。
#import "HelloPlugin.h" @implementation HelloPlugin - (void) nativeFunction:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options { //get the callback id NSString *callbackId = [arguments pop]; NSLog(@"Hello, this is a native function called from PhoneGap/Cordova!"); NSString *resultType = [arguments objectAtIndex:0]; CDVPluginResult *result; if ( [resultType isEqualToString:@"success"] ) { result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: @"Success :)"]; [self writeJavascript:[result toSuccessCallbackString:callbackId]]; } else { result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString: @"Error :("]; [self writeJavascript:[result toErrorCallbackString:callbackId]]; } } @end
在 nativeFunction
方法內部,您首先需要擷取一個 NSString callbackId
引用,核心 PhoneGap API 藉此將此函數響應映射到調用此函數的原始 JavaScript。
接下來,此方法使用 NSLog
將訊息寫入 Xcode 偵錯主控台;這隻是表明它目前正在執行機器碼。
寫入到偵錯主控台後,該函數將會檢查傳遞到該函數的 resultType
,然後建立相應的 CDVPluginResult
執行個體。resultType
值是一個簡單字串。如果 resultType
是 success"
,則該函數將建立 success 結果,並使用 [self writeJavascript]
函數將成功回呼函數寫入 JavaScript 層。任何其他 resultType
參數值均將產生 error 結果,並且該函數會將錯誤回調寫入 JavaScript 層。
當您將成功或錯誤回呼函數寫回 JavaScript 時,始終使用 CDVPluginResult 執行個體。但是,您也可以使用 writeJavascript
函數將任意 JavaScript 字串傳遞迴 JavaScript 層。這項技術甚至還可用於將資料從本機層即時推送至 JavaScript 層。
調用外掛程式
鑒於您已經建立外掛程式,因而可以從 PhoneGap 應用程式內部進行調用。
<script type="text/javascript" charset="utf-8" src="HelloPlugin.js"></script>
- 同樣也是在
onDeviceReady()
函數後,添加 JavaScript 以調用本機外掛程式及處理外掛程式結果。添加名為 callNativePlugin
、nativePluginResultHandler
和 nativePluginErrorHandler
的 JavaScript 函數,如下所示:
function callNativePlugin( returnSuccess ) { HelloPlugin.callNativeFunction( nativePluginResultHandler, nativePluginErrorHandler, returnSuccess ); } function nativePluginResultHandler (result) { alert("SUCCESS: \r\n"+result ); } function nativePluginErrorHandler (error) { alert("ERROR: \r\n"+error ); }
callNativePlugin
函數只需調用 JavaScript 的本機外掛程式類介面。當其調用 callNativeFunction
方法時,即會傳遞從機器碼層接收到的成功和錯誤狀態回呼函數。如果本機層成功返回回呼函數,將會調用 nativePluginResultHandler
函數,而當本機層傳回錯誤回調時,則調用 nativePluginErrorHandler
函數。
- 接下來,根據下列代碼添加兩個 JavaScript 按鈕以調用該外掛程式。
<body onload="onBodyLoad()"> <h1>Hey, it's Cordova!</h1> <button onclick="callNativePlugin('success');">Click to invoke the Native Plugin with an SUCCESS!</button> <button onclick="callNativePlugin('error');">Click to invoke the Native Plugin with an ERROR!</button> </body>
單擊第一個按鈕將調用 callNativeFunction
方法,同時產生參數 "success"。PhoneGap 將於隨後執行機器碼並在 JavaScript 層調用成功回調(它將會調用 nativePluginResultHandler
函數)。
當您單擊第二個按鈕時,將會調用 callNativeFunction
方法,同時產生參數 "error"。PhoneGap 將執行機器碼並在 JavaScript 層調用錯誤回調(它將會調用 nativePluginErrorHandler
函數)。
映射機器碼類
此時,您幾乎已將所有事物串聯起來並可準備執行操作,但您還必須再完成一個步驟,才能調用 JavaScript 中的機器碼。
您必須添加一個映射,以便 Cordova 識別您的機器碼類。還記得在調用 Cordova.exec
時用來識別本機類的字串引用嗎?您需要將該字串映射到 Cordova.plist 檔案中的實際類執行個體。Cordova.plist 檔案包含當前 Cordova 項目的所有配置資訊。
key 是 PhoneGap.exec
映射至機器碼類所使用的唯一一個字串引用。value是將要調用的實際本機類名稱。
- 儲存更改。
圖 5. 編輯 Cordova.plist。
現在,您可以啟動該應用程式並進行徹底檢查。
要啟動該應用程式,請單擊 Run 按鈕或選擇 Product > Run。
在 iOS Simulator 中(或串連裝置上)啟動該應用程式後,您將會看到帶有兩個按鈕的簡單介面(參見圖 6)。單擊任一按鈕調用本機外掛程式的機器碼,無論調用成功回調還是錯誤回調,都會通過 JavaScript 顯示一條警告訊息。
圖 6. iOS 模擬器中啟動並執行應用程式。
當調用機器碼時,您還能夠在 Xcode 偵錯主控台視窗中看到輸出內容,反映調用本機外掛程式 NSLog
產生的輸出內容(參見圖 7)。
圖 7. Xcode 偵錯主控台的記錄資訊。
下一步閱讀方向
現在,您已經瞭解如何在 iOS 裝置上開始為 PhoneGap 應用程式建立本機外掛程式。您可以利用這項技術訪問核心 PhoneGap SDK 未顯示的 iOS 架構,包括(但不僅限於)遊戲中心、核心音頻及 Bonjour 架構,或者任何其他機器碼。與此同時,不要忘記檢查開源社區已經開發的大量現有 GitHub PhoneGap 本機外掛程式。
+
本產品經 Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License 許可。Adobe 提供超出該功能、與本產品包含的程式碼範例相關的許可權。