寫在前邊
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目錄下的,根目錄下的沒用,刪掉后項目變得更清晰)
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
4.配置 config.xml文件
<feature name="TestPluginName">
<param name="ios-package" value="TestPlugin" />
</feature>
5.最終效果
點擊網(wǎng)頁上的按鈕,js調(diào)用插件執(zhí)行原生OC代碼的彈框。調(diào)用成功。
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)用插件的關系,如圖:
二、 js與插件間傳遞參數(shù),以及插件回調(diào)js方法
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
效果如圖: