本文内容衔接自Cordova 从安装到创建项目到创建简单自定义插件到添加使用插件总结(一)
- 说明
- 1.下载node.js
- 2.全局安装cordova
- 3.创建项目
- 4.添加平台
- 5.构建iOS项目
- 6.简单的插件开发
- 7.插件打包以及映射js代码给前端开发人员使用
- 8.将插件包加入cordova项目并使用插件
6.简单的插件开发
PS:以下部分参考自:cordova 自定义插件之完整流程、[ios开发Cordova插件] - 支持入参及调回的插件开发、[ios开发Cordova插件] - 插件打包及映射js代码这三篇文章
①打开ios目录下的.xcworkspace
文件。如果项目无法修改请看第五点的tips。
此时的项目是个空项目(不含任何代码,只有cordova项目默认的代码),我们可以像平时新建Xcode项目来写Demo一样随意操作,只不过我们的插件OC代码应该放在蓝色标注Plugins文件夹下面。
按照看了许多文档的总结来看,我们开发插件的工作就应该在空项目中进行,然后开发完成后再用plugman
对插件进行打包,最后再导入我们需要用到插件的cordova项目,在js代码中引用我们的插件进行对应操作(后续会讲到)。就像我们平时搞个什么东西会新建一个Demo工程,然后在里面弄半天,最后只把最后成型的东西融到我们自己的项目中一样。
②在Plugins目录下新建一个类,该类继承自cordova框架的CDVPlugin(想要与js交互的类都必须继承自此类)。
此时.h中的
#import <Cordova/Cordova.h>
会报错,我们把它改成下面的样子就好
#import <Cordova/CDVPlugin.h>
③在.m添加想要进行的js与OC交互的逻辑,并在.h声明方法。
.h
@interface MyTestClass : CDVPlugin
//必须带上该参数,否则无法与js交互(无法接收js传过来的参数,无法回调js,甚至无法正常调用)
- (void)ocPresentViewControllerWithCommand:(CDVInvokedUrlCommand *)command;
@end
.m这里添加了一个给js调用模态弹出一个原生ViewController的方法。当然这里可能有不合理的地方,只是为了展示层级关系在这里举个例子。
.m
@interface MyTestClass (){
CDVInvokedUrlCommand *_command;
}
@end
@implementation MyTestClass
- (void)ocPresentViewControllerWithCommand:(CDVInvokedUrlCommand *)command{
_command = command;
if (command.arguments.count>0) {
//获取到入参数组中的第一个元素
//与js端开发人员约定传参内容和顺序,然后再这里取来用
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{
//如果没有入参,则回调JS失败函数
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"没有入参参数"];
//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传递的参数\n%@", argument];
label.numberOfLines = 0;
[label sizeToFit];
return label;
}
- (void)dismissViewController{
[self.viewController dismissViewControllerAnimated:YES completion:^{
//创建一个回调对象并附上String类型参数
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"OC代码将模态弹出的控制器取消了,现在是JS代码弹出了这个窗口。"];
//通过cordova框架中的callBackID回调至JS的回调函数上
[self.commandDelegate sendPluginResult:pluginResult callbackId:_command.callbackId];
}];
}
@end
④配置config.xml文件
在Staging下的config.xml文件中添加以下代码,建议添加在文件内容相同格式部分的末尾。
<feature name="ocViewControllerModel">//js调用我们的类的时候创建的实例对象的名字(下面js调用的时候会用到)
<param name="ios-package" value="MyTestClass" />//该对象的类名
</feature>
⑤编写js代码调用我们的插件进行测试
这部分的代码借鉴了[ios开发Cordova插件] - 支持入参及调回的插件开发一文的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">
//调用OC插件方法
function presentViewController() {
//以字符串形式调用OC注入模型的实例方法
//通过cordova 将我们的模型名称(刚才添加的配置文件中的name)
//方法名(我们暴露在.h中的方法名)
//成功回调的func及失败回调的func 传入
cordova.exec(alertSuccess,
alertFail,
"ocViewControllerModel",
"ocPresentViewControllerWithCommand",
["Hey,I'm JS!"]);
}
//调用成功的回调函数
function alertSuccess(msg) {
alert(msg);
}
//调用失败的回调函数
function alertFail(msg) {
alert('调用OC失败: ' + msg);
}
</script>
</head>
<body style="padding-top:50px">
<button style="font-size:17px;" onclick="presentViewController();">调用OC插件</button> <br>
</body>
</html>
到这里自定义简单插件的工作就算结束了,我们可以运行Xcode项目看看效果。其大概流程就是:
<1>App一打开运行Staging下www文件夹中的index.html代码,在界面上显示一个js的按钮。
<2>编译的时候cordova会把config.xml中用<feature> </feature>
包起来的所有内容,根据我们填写的类名和对象名称创建对象,并注入WebView等待调用。
<3>点击按钮后执行cordova.exec(alertSuccess,alertFail,"ocViewControllerModel","ocPresentViewControllerWithCommand",["Hey,I'm JS!"]);
函数。
<3>cordova通过我们传入的ocViewControllerModel对象名,和ocPresentViewControllerWithCommand方法名去调用之前注入的同名对象的对应方法。(所以这里的对象名和之前配置文件的对象名一定要一样,并且保证方法名的正确,不然就无法正常调用。)
<4>然后执行插件中的OC代码(在这里就是ocPresentViewControllerWithCommand方法里面的代码,因为传的是这个方法名)
<5>OC代码执行完之后执行回调函数。
<6>js接收到回调函数执行对应操作。(这里就是function alertSuccess(msg)和function alertFail(msg))
再一次声明目前为止的流程相当于我们平时在新写一个东西的时候的Demo练手加上测试。实际开发中不应该在开发项目中构建的Xcode项目里面这么搞。而是应该打包插件并做js映射,把js调用映射方法部分的逻辑交由前端完成,最后构建出来的xcode项目就是直接包含了oc与js交互部分逻辑的项目。