Cordova学习笔记-4.Cordova插件:自己编写插件

写在前边

cordova框架可以让h5页面调用硬件,比如手机拍照等.这部分其实是需要原声代码支持的,cordova框架做的是h5页面和原生代码的中间件.硬件调用的功能有原生代码实现,不同平台(安卓/ios/window等)需要不同平台单独编写.这些原生代码叫做插件(plugin).h5代码负责显示内容,交互需要调用js代码,js再调用插件,插件执行可以调用手机硬件的方法,然后将返回值传递给js的回调方法,完成整个交互过程.这些插件可以自己编写,需要继承Cordova框架提供的类,在iOS平台,这些插件需要继承CDVPlugins类.这些插件也可以在网上下载,Cordova官网和Github都有非常丰富的插件可以供用户下载使用.
cordova版本:6.5.0

目录

1. 自己编写插件流程
2. js与插件间传递参数,以及插件回调js方法
3. 下载第三方插件

一、自己编写插件流程

示例代码下载地址
github传送门

1.新建一个空白项目,打开后删除掉没用的目录,以免混淆视听:

(config.xml 和www文件夹都是使用Staging目录下的,根目录下的没用,删掉后项目变得更清晰)


新建项目.png
删除没用的项目.png
2.用以下代码完全替换www文件夹下的index.html文件的代码
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
            <meta name="format-detection" content="telephone=no" />
            <title>首页</title>
            
            <style>
                .ui-margin {
                    width: 300px;
                    height: 64px;
                }
            .ui-block-a {
                font-size: 16px;
                margin: 4px;
                padding: 4px;
                width: 180px;
                height: 32px;
            }
            </style>
            
            <script type="text/javascript" src="cordova.js"></script>
            <script type="text/javascript" src="js/index.js"></script>
            
            <script>
                var JSObject = new Object();
                JSObject.IsMobile = function () {
                    return navigator.platform.indexOf('Win32') == -1;
                };
                JSObject.SupportCovdova = function () {
                    return typeof (cordova) != "undefined";
                };
                JSObject.testCordovaPlugin = function() {
                    console.log("testJS");
                    //alert("IsMobile:"+this.IsMobile());
                    //alert("SupportCovdova:"+this.SupportCovdova());
                    if (!this.IsMobile() || !this.SupportCovdova()) {
                        alert("不支持Cordova");
                        return;
                    }
                    cordova.exec(null, null, "TestPluginName", "testPluginFunction", null);
                };
            </script>
            
            </head>
    <body>
        <div class="ui-margin"></div>
        <div>
            <input class="ui-block-a" type="button" value="调用插件" onclick="JSObject.testCordovaPlugin()" />
        </div>
    </body>
</html>
3.编写插件,目录和代码如下
//TestPlugin.h
#import <Cordova/CDVPlugin.h>

@interface TestPlugin : CDVPlugin
-(void)testPluginFunction:(CDVInvokedUrlCommand *)command;
@end

//TestPlugin.m
#import "TestPlugin.h"

@implementation TestPlugin
-(void)testPluginFunction:(CDVInvokedUrlCommand *)command{
    UIAlertController *ac = [UIAlertController alertControllerWithTitle:@"提示" message:@"testPluginFunction" preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction *aa = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:nil];
    [ac addAction:aa];
    [self.viewController presentViewController:ac animated:YES completion:nil];
}
@end
插件目录.png
4.配置 config.xml文件
<feature name="TestPluginName">
       <param name="ios-package" value="TestPlugin" />
</feature>
配置文件.png
5.最终效果

点击网页上的按钮,js调用插件执行原生OC代码的弹框。调用成功。


执行效果.png
6.稍微总结一下
1. js代码调用插件时,可以使用以下代码判断当前是否支持cordova
 function SupportCovdova() {
      return typeof (cordova) != "undefined";
};

如果不支持cordova,记得引入cordova.js
<script type="text/javascript" src="cordova.js"></script>

2. 说明一下js代码调用插件的关系,如图:
说明.png

二、 js与插件间传递参数,以及插件回调js方法

去github上下载示例代码

JS通过cordova.exec()方法调用插件时,可以传入插件方法需要的参数,和插件将来回调的js参数。

//执行cordova插件,五个参数分别是:
//成功回调方法,失败回调方法,插件名(配置文件中配置的插件名),插件方法,传入插件的参数(数组类型,可传入多个参数)
cordova.exec(this.testSuccess, this.testFail, "TestPluginName", "testPluginFunctionWithArgumentsAndCallBack", [{"name" : "小明"}, {"age" : "9"}, {"frends" : ["小白", "小溪"]}]);

插件方法
-(void)testPluginFunctionWithArgumentsAndCallBack:(CDVInvokedUrlCommand *)command{}
的参数CDVInvokedUrlCommand *command 有四个成员变量:
//***CDVInvokedUrlCommand的四个成员变量, NSString *callbackId = command.callbackId; NSString *className = command.className; NSString *methodName = command.methodName; NSArray *arguments = command.arguments;
其中command.arguments就是js调用插件时传过来那个参数(数组类型),command.callbackId用来在插件中回调js回调方法时使用:

 NSArray *array = @[@"返回参数1", @"返回参数2"];
//CDVPluginResult 的status属性是只读属性,初始化方法“resultWithStatus: messageAsArray:”的第一个参数传入CDVCommandStatus_OK时,调用js的成功回调方法,传入其他的值都执行js的失败回调方法
//回调js的成功回调方法
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:array];
[self.commandDelegate sendPluginResult:result callbackId:self.callbackId];

示例代码:

//JS代码
var JSObject = new Object();
JSObject.IsMobile = function () {
    return navigator.platform.indexOf('Win32') == -1;
};
JSObject.SupportCovdova = function () {
    return typeof (cordova) != "undefined";
};
JSObject.testCordovaPluginWithArgumentsAndCallBack = function() {
    console.log("testJS");
    
    if (!this.IsMobile() || !this.SupportCovdova()) {
        alert("不支持Cordova");
        return;
    }
    //执行cordova插件,五个参数分别是:
    //成功回调方法,失败回调方法,插件名(配置文件中配置的插件名),插件方法,传入插件的参数(数组类型,可传入多个参数)
    cordova.exec(this.testSuccess, this.testFail, "TestPluginName", "testPluginFunctionWithArgumentsAndCallBack", [{"name" : "小明"}, {"age" : "9"}, {"frends" : ["小白", "小溪"]}]);
};
JSObject.testSuccess = function(result) {
    alert("JS成功回调方法:testSuccess\n\n"+result);
}
JSObject.testFail = function(result) {
    alert("JS失败回调方法:testFail\n\n"+result);
}
//OC插件代码
#import "TestPlugin.h"

@interface TestPlugin()
@property(nonatomic,strong) NSString *callbackId;
@end

@implementation TestPlugin

-(void)testPluginFunctionWithArgumentsAndCallBack:(CDVInvokedUrlCommand *)command{
    
    //***CDVInvokedUrlCommand的四个成员变量,
    NSString *callbackId = command.callbackId;
    NSString *className = command.className;
    NSString *methodName = command.methodName;
    NSArray *arguments = command.arguments;
    NSLog(@"callbackId:%@",callbackId);
    NSLog(@"className:%@",className);
    NSLog(@"methodName:%@",methodName);
    NSLog(@"arguments:%@",arguments);
    
    //***打印传入的参数
    NSString *argumentsStr = @"";
    for (NSDictionary *dict in command.arguments) {
        for (NSString *key in dict.allKeys) {
            NSObject *object = [dict objectForKey:key];
            if ([object isKindOfClass:[NSString class]]) {
                argumentsStr = [NSString stringWithFormat:@"%@%@=%@\n",argumentsStr,key,object];
            } else if([object isKindOfClass:[NSArray class]]){
                argumentsStr = [NSString stringWithFormat:@"%@%@:\n",argumentsStr,key];
                for (NSObject *subObject in (NSArray *)object) {
                    if ([subObject isKindOfClass:[NSString class]]) {
                        argumentsStr = [NSString stringWithFormat:@"%@%@\n",argumentsStr,subObject];
                    }
                }
            }
        }
    }
    
    self.callbackId = command.callbackId;
    [self alertMessage:argumentsStr andTitle:@"OC弹框"];
}

//弹出提示信息
-(void)alertMessage:(NSString *)message andTitle:(NSString *)title{
    UIAlertController *ac = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction *aaYES = [UIAlertAction actionWithTitle:@"成功" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        //***回调JS方法
        NSArray *array = @[@"返回参数1", @"返回参数2"];
        //CDVPluginResult 的status属性是只读属性,初始化方法“resultWithStatus: messageAsArray:”的第一个参数传入CDVCommandStatus_OK时,调用js的成功回调方法,传入其他的值都执行js的失败回调方法
        //回调js的成功回调方法
        CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:array];
        [self.commandDelegate sendPluginResult:result callbackId:self.callbackId];
    }];
    
    UIAlertAction *aaNO = [UIAlertAction actionWithTitle:@"失败" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        //***回调JS方法
        NSArray *array = @[@"返回参数1", @"返回参数2"];
        //CDVPluginResult 的status属性是只读属性,初始化方法“resultWithStatus: messageAsArray:”的第一个参数传入CDVCommandStatus_OK时,调用js的成功回调方法,传入其他的值都执行js的失败回调方法
        //回调js的失败回调方法
        CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsArray:array];
        [self.commandDelegate sendPluginResult:result callbackId:self.callbackId];
    }];
    
    [ac addAction:aaYES];
    [ac addAction:aaNO];
    [self.viewController presentViewController:ac animated:YES completion:nil];
}

@end

效果如图:

效果图.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容