本文內(nèi)容銜接自Cordova 從安裝到創(chuàng)建項目到創(chuàng)建簡單自定義插件到添加使用插件總結(jié)(一)
- 說明
- 1.下載node.js
- 2.全局安裝cordova
- 3.創(chuàng)建項目
- 4.添加平臺
- 5.構(gòu)建iOS項目
- 6.簡單的插件開發(fā)
- 7.插件打包以及映射js代碼給前端開發(fā)人員使用
- 8.將插件包加入cordova項目并使用插件
6.簡單的插件開發(fā)
PS:以下部分參考自:cordova 自定義插件之完整流程、[ios開發(fā)Cordova插件] - 支持入?yún)⒓罢{(diào)回的插件開發(fā)、[ios開發(fā)Cordova插件] - 插件打包及映射js代碼這三篇文章
①打開ios目錄下的.xcworkspace文件。如果項目無法修改請看第五點的tips。

此時的項目是個空項目(不含任何代碼,只有cordova項目默認(rèn)的代碼),我們可以像平時新建Xcode項目來寫Demo一樣隨意操作,只不過我們的插件OC代碼應(yīng)該放在藍(lán)色標(biāo)注Plugins文件夾下面。
按照看了許多文檔的總結(jié)來看,我們開發(fā)插件的工作就應(yīng)該在空項目中進(jìn)行,然后開發(fā)完成后再用plugman對插件進(jìn)行打包,最后再導(dǎo)入我們需要用到插件的cordova項目,在js代碼中引用我們的插件進(jìn)行對應(yīng)操作(后續(xù)會講到)。就像我們平時搞個什么東西會新建一個Demo工程,然后在里面弄半天,最后只把最后成型的東西融到我們自己的項目中一樣。
②在Plugins目錄下新建一個類,該類繼承自cordova框架的CDVPlugin(想要與js交互的類都必須繼承自此類)。

此時.h中的
#import <Cordova/Cordova.h>
會報錯,我們把它改成下面的樣子就好
#import <Cordova/CDVPlugin.h>
③在.m添加想要進(jìn)行的js與OC交互的邏輯,并在.h聲明方法。
.h
@interface MyTestClass : CDVPlugin
//必須帶上該參數(shù),否則無法與js交互(無法接收js傳過來的參數(shù),無法回調(diào)js,甚至無法正常調(diào)用)
- (void)ocPresentViewControllerWithCommand:(CDVInvokedUrlCommand *)command;
@end
.m這里添加了一個給js調(diào)用模態(tài)彈出一個原生ViewController的方法。當(dāng)然這里可能有不合理的地方,只是為了展示層級關(guān)系在這里舉個例子。
.m
@interface MyTestClass (){
CDVInvokedUrlCommand *_command;
}
@end
@implementation MyTestClass
- (void)ocPresentViewControllerWithCommand:(CDVInvokedUrlCommand *)command{
_command = command;
if (command.arguments.count>0) {
//獲取到入?yún)?shù)組中的第一個元素
//與js端開發(fā)人員約定傳參內(nèi)容和順序,然后再這里取來用
id argument = command.arguments[0];
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = [UIColor whiteColor];
[vc.view addSubview:[self creatLabelWithArgument:argument]];
[vc.view addSubview:[self creatBackButton]];
//self.viewController為CDVPlugin類自帶的屬性
//為加載js代碼的webView所在的控制器。
[self.viewController presentViewController:vc animated:YES completion:nil];
}else{
//如果沒有入?yún)?則回調(diào)JS失敗函數(shù)
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"沒有入?yún)?shù)"];
//self.commandDelegate不需要賦值,直接使用,也是CDVPlugin自帶的。
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
}
- (UIButton *)creatBackButton{
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(10, 20, 40, 20)];
[btn setTitle:@"返回" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(dismissViewController) forControlEvents:UIControlEventTouchUpInside];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
return btn;
}
- (UILabel *)creatLabelWithArgument:(id)argument{
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 200, 0)];
label.text = [NSString stringWithFormat:@"我是OC代碼present的控制器,接收到JS傳遞的參數(shù)\n%@", argument];
label.numberOfLines = 0;
[label sizeToFit];
return label;
}
- (void)dismissViewController{
[self.viewController dismissViewControllerAnimated:YES completion:^{
//創(chuàng)建一個回調(diào)對象并附上String類型參數(shù)
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"OC代碼將模態(tài)彈出的控制器取消了,現(xiàn)在是JS代碼彈出了這個窗口。"];
//通過cordova框架中的callBackID回調(diào)至JS的回調(diào)函數(shù)上
[self.commandDelegate sendPluginResult:pluginResult callbackId:_command.callbackId];
}];
}
@end
④配置config.xml文件
在Staging下的config.xml文件中添加以下代碼,建議添加在文件內(nèi)容相同格式部分的末尾。
<feature name="ocViewControllerModel">//js調(diào)用我們的類的時候創(chuàng)建的實例對象的名字(下面js調(diào)用的時候會用到)
<param name="ios-package" value="MyTestClass" />//該對象的類名
</feature>
⑤編寫js代碼調(diào)用我們的插件進(jìn)行測試
這部分的代碼借鑒了[ios開發(fā)Cordova插件] - 支持入?yún)⒓罢{(diào)回的插件開發(fā)一文的js代碼。
將Staging下www文件夾中的index.html代碼替換為以下代碼
<!DOCTYPE html>
<html>
<head>
<title>AMAlert</title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script type="text/javascript" charset="utf-8">
//調(diào)用OC插件方法
function presentViewController() {
//以字符串形式調(diào)用OC注入模型的實例方法
//通過cordova 將我們的模型名稱(剛才添加的配置文件中的name)
//方法名(我們暴露在.h中的方法名)
//成功回調(diào)的func及失敗回調(diào)的func 傳入
cordova.exec(alertSuccess,
alertFail,
"ocViewControllerModel",
"ocPresentViewControllerWithCommand",
["Hey,I'm JS!"]);
}
//調(diào)用成功的回調(diào)函數(shù)
function alertSuccess(msg) {
alert(msg);
}
//調(diào)用失敗的回調(diào)函數(shù)
function alertFail(msg) {
alert('調(diào)用OC失敗: ' + msg);
}
</script>
</head>
<body style="padding-top:50px">
<button style="font-size:17px;" onclick="presentViewController();">調(diào)用OC插件</button> <br>
</body>
</html>
到這里自定義簡單插件的工作就算結(jié)束了,我們可以運(yùn)行Xcode項目看看效果。其大概流程就是:
<1>App一打開運(yùn)行Staging下www文件夾中的index.html代碼,在界面上顯示一個js的按鈕。
<2>編譯的時候cordova會把config.xml中用<feature> </feature>包起來的所有內(nèi)容,根據(jù)我們填寫的類名和對象名稱創(chuàng)建對象,并注入WebView等待調(diào)用。
<3>點擊按鈕后執(zhí)行cordova.exec(alertSuccess,alertFail,"ocViewControllerModel","ocPresentViewControllerWithCommand",["Hey,I'm JS!"]);函數(shù)。
<3>cordova通過我們傳入的ocViewControllerModel對象名,和ocPresentViewControllerWithCommand方法名去調(diào)用之前注入的同名對象的對應(yīng)方法。(所以這里的對象名和之前配置文件的對象名一定要一樣,并且保證方法名的正確,不然就無法正常調(diào)用。)
<4>然后執(zhí)行插件中的OC代碼(在這里就是ocPresentViewControllerWithCommand方法里面的代碼,因為傳的是這個方法名)
<5>OC代碼執(zhí)行完之后執(zhí)行回調(diào)函數(shù)。
<6>js接收到回調(diào)函數(shù)執(zhí)行對應(yīng)操作。(這里就是function alertSuccess(msg)和function alertFail(msg))
再一次聲明目前為止的流程相當(dāng)于我們平時在新寫一個東西的時候的Demo練手加上測試。實際開發(fā)中不應(yīng)該在開發(fā)項目中構(gòu)建的Xcode項目里面這么搞。而是應(yīng)該打包插件并做js映射,把js調(diào)用映射方法部分的邏輯交由前端完成,最后構(gòu)建出來的xcode項目就是直接包含了oc與js交互部分邏輯的項目。
后續(xù)內(nèi)容請?zhí)D(zhuǎn)Cordova 從安裝到創(chuàng)建項目到創(chuàng)建簡單自定義插件到添加使用插件總結(jié)(三)