ionic

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

2016-06-16  本文已影响607人  ImmortalSummer

写在前边

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
上一篇下一篇

猜你喜欢

热点阅读