Cordova學習筆記-4.Cordova插件:自己編寫插件

寫在前邊

cordova框架可以讓h5頁面調(diào)用硬件,比如手機拍照等.這部分其實是需要原聲代碼支持的,cordova框架做的是h5頁面和原生代碼的中間件.硬件調(diào)用的功能有原生代碼實現(xiàn),不同平臺(安卓/ios/window等)需要不同平臺單獨編寫.這些原生代碼叫做插件(plugin).h5代碼負責顯示內(nèi)容,交互需要調(diào)用js代碼,js再調(diào)用插件,插件執(zhí)行可以調(diào)用手機硬件的方法,然后將返回值傳遞給js的回調(diào)方法,完成整個交互過程.這些插件可以自己編寫,需要繼承Cordova框架提供的類,在iOS平臺,這些插件需要繼承CDVPlugins類.這些插件也可以在網(wǎng)上下載,Cordova官網(wǎng)和Github都有非常豐富的插件可以供用戶下載使用.
cordova版本:6.5.0

目錄

1. 自己編寫插件流程
2. js與插件間傳遞參數(shù),以及插件回調(diào)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="調(diào)用插件" 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.最終效果

點擊網(wǎng)頁上的按鈕,js調(diào)用插件執(zhí)行原生OC代碼的彈框。調(diào)用成功。


執(zhí)行效果.png
6.稍微總結(jié)一下
1. js代碼調(diào)用插件時,可以使用以下代碼判斷當前是否支持cordova
 function SupportCovdova() {
      return typeof (cordova) != "undefined";
};

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

2. 說明一下js代碼調(diào)用插件的關系,如圖:
說明.png

二、 js與插件間傳遞參數(shù),以及插件回調(diào)js方法

去github上下載示例代碼

JS通過cordova.exec()方法調(diào)用插件時,可以傳入插件方法需要的參數(shù),和插件將來回調(diào)的js參數(shù)。

//執(zhí)行cordova插件,五個參數(shù)分別是:
//成功回調(diào)方法,失敗回調(diào)方法,插件名(配置文件中配置的插件名),插件方法,傳入插件的參數(shù)(數(shù)組類型,可傳入多個參數(shù))
cordova.exec(this.testSuccess, this.testFail, "TestPluginName", "testPluginFunctionWithArgumentsAndCallBack", [{"name" : "小明"}, {"age" : "9"}, {"frends" : ["小白", "小溪"]}]);

插件方法
-(void)testPluginFunctionWithArgumentsAndCallBack:(CDVInvokedUrlCommand *)command{}
的參數(shù)CDVInvokedUrlCommand *command 有四個成員變量:
//***CDVInvokedUrlCommand的四個成員變量, NSString *callbackId = command.callbackId; NSString *className = command.className; NSString *methodName = command.methodName; NSArray *arguments = command.arguments;
其中command.arguments就是js調(diào)用插件時傳過來那個參數(shù)(數(shù)組類型),command.callbackId用來在插件中回調(diào)js回調(diào)方法時使用:

 NSArray *array = @[@"返回參數(shù)1", @"返回參數(shù)2"];
//CDVPluginResult 的status屬性是只讀屬性,初始化方法“resultWithStatus: messageAsArray:”的第一個參數(shù)傳入CDVCommandStatus_OK時,調(diào)用js的成功回調(diào)方法,傳入其他的值都執(zhí)行js的失敗回調(diào)方法
//回調(diào)js的成功回調(diào)方法
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;
    }
    //執(zhí)行cordova插件,五個參數(shù)分別是:
    //成功回調(diào)方法,失敗回調(diào)方法,插件名(配置文件中配置的插件名),插件方法,傳入插件的參數(shù)(數(shù)組類型,可傳入多個參數(shù))
    cordova.exec(this.testSuccess, this.testFail, "TestPluginName", "testPluginFunctionWithArgumentsAndCallBack", [{"name" : "小明"}, {"age" : "9"}, {"frends" : ["小白", "小溪"]}]);
};
JSObject.testSuccess = function(result) {
    alert("JS成功回調(diào)方法:testSuccess\n\n"+result);
}
JSObject.testFail = function(result) {
    alert("JS失敗回調(diào)方法: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);
    
    //***打印傳入的參數(shù)
    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) {
        //***回調(diào)JS方法
        NSArray *array = @[@"返回參數(shù)1", @"返回參數(shù)2"];
        //CDVPluginResult 的status屬性是只讀屬性,初始化方法“resultWithStatus: messageAsArray:”的第一個參數(shù)傳入CDVCommandStatus_OK時,調(diào)用js的成功回調(diào)方法,傳入其他的值都執(zhí)行js的失敗回調(diào)方法
        //回調(diào)js的成功回調(diào)方法
        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) {
        //***回調(diào)JS方法
        NSArray *array = @[@"返回參數(shù)1", @"返回參數(shù)2"];
        //CDVPluginResult 的status屬性是只讀屬性,初始化方法“resultWithStatus: messageAsArray:”的第一個參數(shù)傳入CDVCommandStatus_OK時,調(diào)用js的成功回調(diào)方法,傳入其他的值都執(zhí)行js的失敗回調(diào)方法
        //回調(diào)js的失敗回調(diào)方法
        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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容