11、iOS開發詳解(基礎知識)
iOS開發詳解
本章節針對如何開發基於iOS系統的外掛進行介紹,在此之前,請閱讀Plugin Development Guide(外掛開發指南)對外掛的結構和JavaScript介面有一個大概的瞭解。
iOS外掛是以繼承至CDVPlugin類Objective-C的子類來實現的,通過JavaScript的exec函式來將service/parameter對映到Objective-C類,每一個外掛在工程根目錄下的config.xml檔案中通過標籤進行註冊。
外掛類的對映
我們通過如下的Cordova API來實現JavaScript到Objective-C的對映過程:
exec(<successFunction >, <failFunction>, <service>, <action>, [<args>]);
通過這個JavaScript函式我們就可以使用JavaScript程式碼來執行Objective-C類的指定函式,並且通過args來傳遞引數。
通過config.xml中iOS平臺的標籤來指定需要的外掛,通過plugin.xml檔案來自動注入外掛到iOS平臺程式碼中去。
<featurename="LocalStorage"><paramname="ios-package"value="CDVLocalStorage" /></feature>
標籤的name屬性用於指定plugin在JavaScript執行exec方法時service引數的值,為標籤內標籤內value對應的Objective-C類的具體函式名,args以陣列的形式傳入到Objective-C函式內。的name欄位永遠為’ios-package’。
外掛的例項化和生命週期
plugin物件的生命週期和UIWebView是一致的,Plugin是不需要例項化的,在他們第一次被呼叫的時候會自動例項化。也可以通過指定的方式來手動例項化一個plugin比如:
<featurename="Echo"><paramname="ios-package" value="Echo" /><paramname="onload"value="true" /></feature>
當使用的時候,在程式啟動的時候會執行外掛的pluginInitialize方法來例項化一個外掛類物件。你可以通過覆蓋pluginInitialize方法的方式在程式啟動的時候為你的外掛做點什麼。
Plugin進行耗時操作的時候,比如媒體操作,監聽,或者網路狀態相關的事情,應該提供重置和取消操作來終止之前的操作或者請求。當需要轉入新的頁面或者重新整理頁面這種需要重新載入JavaScript的時候被使用。
建立一個iOS plugin
JavaScript通過config.xml配置的對映來發起一個plugin請求來執行Objective-C程式碼,但是最終的Objective-C外掛類什麼樣呢?下面就是plugin的一個方法定義:
- (void)myMethod:(CDVInvokedUrlCommand*)command
{
CDVPluginResult* pluginResult = nil;
NSString* myarg = [command.arguments objectAtIndex:0];
if (myarg != nil) {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
} else {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Arg was null"];
}
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
更多的資訊可以檢視CDVInvokedUrlCommand.h, CDVPluginResult.h, CDVCommandDelegate.h這三個Cordova原始碼檔案。
iOS CDVPluginResult類
你可以使用CDVPluginResult類來返回各種型別的結果資訊給JavaScript的回撥函式,通過以下的方式來建立一個CDVPluginResult物件:
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAs...
你可以返回字串,整數,布林,陣列以及複合資料型別等,你也可以僅僅返回一個狀態資訊或者錯誤資訊,當然你也可以不返回任何資訊僅僅呼叫JavaScript端的回撥函式。
下面複雜型別的返回值的使用方法:
messageAsArrayBuffer以NSData的形式被傳送到JavaScript回撥函式,並且被轉換為ArrayBuffer型別,而ArrayBuffer在傳入到Objective-C端的時候會被轉換成NSData。
messageAsMultipart以NSArray的形式被傳入到JavaScript回撥函式,裡面包含各種型別的資料物件。通過這種方式傳送資料,裡面的資料會被序列化和反序列化,所以他可以安全的返回NSData,而不是Array/Dictionary。
Echo iOS Plugin(這篇文章對於plugin的配置在使用cordova build命令以後會被覆蓋,不建議在iOS工程直接加入檔案修改配置檔案資訊的方式新增外掛。使用獨立外掛通過plugin add的方式新增外掛比較容易維護和使用)
這個例子通過plugin.xml來向指定的iOS平臺注入資訊。
<platformname="ios"><config-filetarget="config.xml"parent="/*"><featurename="Echo"><paramname="ios-package"value="Echo" /></feature></config-file></platform>
新增Echo.h檔案和Echo.m檔案到iOS映象的資料夾的Plugins資料夾:
/********* Echo.h Cordova Plugin Header *******/#import <Cordova/CDVPlugin.h>
@interface Echo : CDVPlugin
- (void)echo:(CDVInvokedUrlCommand*)command;
@end
/********* Echo.m Cordova Plugin Implementation *******/#import "Echo.h"#import <Cordova/CDVPlugin.h>
@implementation Echo
- (void)echo:(CDVInvokedUrlCommand*)command
{
CDVPluginResult* pluginResult = nil;
NSString* echo = [command.arguments objectAtIndex:0];
if (echo != nil && [echo length] > 0) {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:echo];
} else {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
}
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
@end
上面的類繼承至CDVPlugin類,在這裡,Echo外掛只有一個功能。就是返回JavaScript傳入的第一個引數內容。如果沒有傳入引數則返回錯誤,如果傳入引數,則將該引數返回。
CDVPlugin簡介
CDVPlugin類包含其他的一些方法,你可以通過重寫的方式來實現自己的行為,比如捕獲pause,resume等等。具體可以去讀CDVPlugin.h/CDVPlugin.m原始檔
Threading
我們在plugin裡面經常需要做一些耗時的操作,但是在主執行緒耗時過長,App就會被系統kill。所以通過runInBackground來進行耗時操作:
- (void)myPluginMethod:(CDVInvokedUrlCommand*)command
{
// Check command.arguments here.
[self.commandDelegate runInBackground:^{
NSString* payload = nil;
// Some blocking logic...
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:payload];
// The sendPluginResult method is thread-safe.
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}];
}
除錯plugin
使用Xcode來除錯plugin,如果除錯JavaScript程式碼,需要使用Safari在虛擬機器或者裝置上除錯。
易犯錯誤
不要忘記在config.xml新增對映資訊。