官方
插件開(kāi)發(fā)指南
Plugin.xml
因本人比較熟悉iOS , 所以創(chuàng)建的plugin 以iOS 為主, android 簡(jiǎn)單的涉及.
我們知道cordova plugin 是原生與html溝通的橋梁, cordova 可以說(shuō)是一個(gè)webView,加載一個(gè)大的html 頁(yè)面.相關(guān)的版面以html 網(wǎng)頁(yè)的形式出現(xiàn),而cordova plugin ,就好像你要打開(kāi)手機(jī)的相機(jī)功能,單靠html是完成不了這個(gè)功能的.所以就需要cordova plugin的存在, 它異常的重要.
目標(biāo)
這樣添加plugin
希望我們最后這樣使用就可以添加到cordova-plugin: (因未在registry.cordova.io中注冊(cè).暫指定備用URL)
cordova plugin add https://github.com/apache/cordova-plugin-console.git
- 也可以在https://github.com/apache/cordova-plugin-console.git => 后面加 #
在#字符后面附加備用git-ref,例如 標(biāo)記或分支:
cordova plugin add https://github.com/apache/cordova-plugin-console.git#r0.2.0
- 如果插件(及其plugin.xml文件)位于git repo中的子目錄中,則可以使用:字符指定它。請(qǐng)注意,#仍然需要該 角色:
cordova plugin add https://github.com/someone/aplugin.git#:/my/sub/dir
- 還可以將git-ref和子目錄結(jié)合使用:
cordova plugin add https://github.com/someone/aplugin.git#r0.0.1:/my/sub/dir
- 或者,指定包含該plugin.xml文件的插件目錄的本地路徑:
cordova plugin add ../my_plugin_dir
刪除plugin
cordova plugin rm pluginName(可以打開(kāi)本地plugin list 看, 也可以執(zhí)行 cordova plugin list 看)
開(kāi)始創(chuàng)建我們的Plugin
-
插件文件夾必須具有plugin.xml清單文件,所以我們可以簡(jiǎn)單地創(chuàng)建一個(gè)plugin.xml文件, 然后我們開(kāi)始對(duì)里面的參數(shù)做一一講解
plugin.xml
用工具打開(kāi)plugin.xml.
<?xml version="1.0" encoding="UTF-8"?>
<!-- xmlns: Required , 插件名稱空間,http://apache.org/cordova/ns/plugins/1.0。 如果文檔包含來(lái)自其他命名空間的XML,例如在Android的情況下要添加到AndroidManifest.xml文件的標(biāo)記,那么這些命名空間也應(yīng)該包含在元素中。-->
<!-- id, Required ,通常是this-is-a-plugin的形式,就像cordova-plugin-device(作為示例) -->
<!-- version,Required, 插件的版本號(hào) -->
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android" id="cordova-plugin-netspay" version="0.1.0">
<!-- name,用于指定插件的名稱。(尚未)處理本地化。-->
<name>netspay</name>
<!--description用于指定插件的描述.(尚未)處理本地化。-->
<description>Cordova Plugin netspay</description>
<!--author包含插件作者的名稱。-->
<author>peijue chen</author>
<!--關(guān)鍵字元素的內(nèi)容,可以用逗號(hào)分隔的-->
<keywords>cordova, plugin, enets, netspay</keywords>
<!--此元素用于指定插件的許可證。-->
<license>MIT</license>
<!---如果有pod , 請(qǐng)?zhí)砑哟?
如果不添加這個(gè),請(qǐng)先安裝: cordova plugin add cordova-plugin-cocoapod-support --save
--->
<dependency id="cordova-plugin-cocoapod-support"/>
<!-- 指定的cordova 版本, 如果安裝時(shí)比它小, cordova 會(huì)終止.如果不指定,cordova 會(huì)不管三七二十一安裝.-->
<!-- name : cordova/cordova-ios/cordova-android....-->
<!-- <engines>
<engine name="cordova" version=">=4.0.0" />
<engine name="cordova-android" version=">=4.0.0" />
<engine name="cordova-ios" version=">=1.7.1" />
</engines> -->
<!-- Custom frameworks example:-->
<!--
<engines>
<engine name="my_custom_framework" version="1.0.0" platform="android" scriptSrc="path_to_my_custom_framework_version"/>
<engine name="another_framework" version=">0.2.0" platform="ios|android" scriptSrc="path_to_another_framework_version"/>
<engine name="even_more_framework" version=">=2.2.0" platform="*" scriptSrc="path_to_even_more_framework_version"/>
</engines>
-->
<!-- js-module
src:插件目錄中相對(duì)于plugin.xml文件;
name 提供模塊名稱的最后一部分.可以是你喜歡的任何東西,如果你想在你的JavaScript代碼中使用cordova.require導(dǎo)入插件, 這里可以這樣輸入: var netspay = require('./netspay')
<js-module>的模塊名稱是插件的id,后跟name的值。 -->
<!-- clobbers: 用于指定插入module.exports的window對(duì)象下的命名空間。 您可以擁有任意數(shù)量的<clobbers>。 -->
<!-- e.g: window.cordova.plugins.netspay 這里可以這樣使用-->
<js-module src="www/netspay.js" name="netspay">
<clobbers target="cordova.plugins.netspay" />
</js-module>
<!-- 加入多個(gè), 也可以在某個(gè)平臺(tái)單獨(dú)指定
<js-module src="www/PositionError.js" name="PositionError">
<clobbers target="PositionError" />
</js-module>
-->
<!--<dependency>標(biāo)簽允許您指定當(dāng)前插件所依賴的其他插件。 插件由其唯一的 npm id或github url 引用。-->
<!--
<dependency id="cordova-plugin-someplugin" url="https://github.com/myuser/someplugin" commit="428931ada3891801" subdir="some/path/here" />
<dependency id="cordova-plugin-someplugin" version="1.0.1">
-->
<!--如果不指定platform,就當(dāng)作只是JavaScript,可以安裝到任何平臺(tái)-->
<!--Required ,Allowed values: ios, android, windows, browser, osx -->
<!-- android -->
<platform name="android">
<config-file parent="/*" target="res/xml/config.xml">
<feature name="NetsPay">
<param name="android-package" value="cordova-plugin-netspay.NetsPay" />
</feature>
</config-file>
<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" android:protectionLevel="normal" />
<uses-permission android:name="com.nets.netspay.QR_TRANSACTION" />
</config-file>
<source-file src="src/android/NetsPay.java" target-dir="src/cordova-plugin-netspay/NetsPay" />
<framework src="src/android/netspay.gradle" custom="true" type="gradleReference"/>
<resource-file src="src/android/enetslib_UAT_1.2.1.aar" target="libs/enetslib_UAT_1.2.1.aar"/>
<!--
<resource-file src="FooPluginStrings.xml" target="res/values/FooPluginStrings.xml" />
// 添加配置
<config-file target="AndroidManifest.xml" parent="/manifest/application">
<activity android:name="com.foo.Foo" android:label="@string/app_name">
<intent-filter>
</intent-filter>
</activity>
</config-file>
-->
<!---
On Android (as of cordova-android@4.0.0), framework tags are used to include Maven dependencies, or to include bundled library projects.
-->
<!-- Depend on latest version of GCM from play services
<framework src="com.google.android.gms:play-services-gcm:+" />
-->
<!-- Depend on v21 of appcompat-v7 support library
<framework src="com.android.support:appcompat-v7:21+" />
-->
<!-- Depend on library project included in plugin
<framework src="relative/path/FeedbackLib" custom="true" />
-->
<!--
Framework can also be used to have custom .gradle files sub-included into the main project's build.gradle file:
<framework src="relative/path/rules.gradle" custom="true" type="gradleReference" />
On Windows, using custom='true' and type='projectReference' will add a reference to the project which will be added to the compile+link steps of the cordova project. This essentially is the only way currently that a 'custom' framework can target multiple architectures as they are explicitly built as a dependency by the referencing cordova application.
<framework src="path/to/project/LibProj.csproj" custom="true" type="projectReference"/>
Examples of using these Windows specific attributes:
<framework src="src/windows/example.dll" arch="x64" />
<framework src="src/windows/example.dll" versions=">=8.0" />
<framework src="src/windows/example.vcxproj" type="projectReference" target="win" />
<framework src="src/windows/example.vcxproj" type="projectReference" target="all" versions="8.1" arch="x86" />
<framework src="src/windows/example.dll" target-dir="bin/x64" arch="x64" custom="true"/>
-->
<!--
Another example of using Windows-specific attributes to add a reference to WinMD components, written in C# and C++, whose API will be available at runtime:
-->
<!-- C# component that consists of one .winmd file
<framework src="lib\windows\component.winmd" versions="<10.0" />
-->
<!-- C++ component with separated metadata and implementation
<framework src="lib\windows\x86\cppcomponent.winmd"
implementation="lib\windows\x86\cppcomponent.dll"
target-dir="component\x86" arch="x86" versions=">=10.0" />
-->
</platform>
<!-- ios -->
<platform name="ios">
<!--
這個(gè)配置相當(dāng)重要, feature 中的name 你可以寫 上面的id ,
param 的name 寫: ios-package , 但value : 一定要寫你本地的.m /.swift 文件的 class 名字, cordova 要用它來(lái)call 方法.
-->
<config-file target="config.xml" parent="/*">
<feature name="NetsPay">
<param name="ios-package" value="NetsPay" />
</feature>
</config-file>
<!-- 配置info 文件 -->
<!---往info.plist 中添加?xùn)|西, 可以設(shè)置默認(rèn)值, 在外面添加plugin 時(shí)也可以根據(jù)GEOLOCATION_USAGE_DESCRIPTION來(lái)添加, 請(qǐng)往下看-->
<preference name="GEOLOCATION_USAGE_DESCRIPTION" default="Enable access for location helps us to show you nearest stores." />
<config-file target="*-Info.plist" parent="NSLocationWhenInUseUsageDescription">
<string>$GEOLOCATION_USAGE_DESCRIPTION</string>
</config-file>
<!-- add url schemes -->
<config-file target="*-Info.plist" parent="CFBundleURLTypes">
<array>
<dict>
<key>CFBundleURLName</key>
<string>bundle.id</string>
<key>CFBundleURLSchemes</key>
<array>
<string>netspaySchemes</string>
</array>
</dict>
</array>
</config-file>
<!-- 頭文件, 只復(fù)制文件進(jìn)cordova項(xiàng)目, 不參與編譯 -->
<header-file src="src/ios/NetsPay.h" />
<!--安裝到項(xiàng)目中的可執(zhí)行源代碼。-->
<source-file src="src/ios/NetsPay.m" />
<!--<source-file src="src/ios/Netspay.swift" />-->
<!--compiler-flags: 如果設(shè)置,則為特定源文件指定指定的編譯器標(biāo)志。-->
<!--
<source-file src="src/ios/someLib.a" compiler-flags="-fno-objc-arc" />
-->
<!-- 系統(tǒng)庫(kù) -->
<!-- alipay depen -->
<!-- <framework src="libc++.tbd" />
<framework src="libz.tbd" />
<framework src="SystemConfiguration.framework" />
<framework src="CoreTelephony.framework" />
<framework src="QuartzCore.framework" />
<framework src="CoreText.framework" />
<framework src="CoreGraphics.framework" />
<framework src="UIKit.framework" />
<framework src="Foundation.framework" />
<framework src="CFNetwork.framework" />
<framework src="CoreMotion.framework" /> -->
<!-- pod framework 但僅限靜態(tài)庫(kù), 必須: cordova-ios@4.3.0 and cordova-cli 6.4.0
如果使用該屬性, 請(qǐng)?jiān)O(shè)置好 cordova-ios 版本.
-->
<!---或者這種情況-->
<pods-config ios-min-version="8.0" use-frameworks="true"/>
<pod id="GoogleConversionTracking" version="3.4.0"/>
<pod id="FirebaseAppIndexing" version="1.0.3"/>
<!-- <framework src="OrderPlaceSdk" type="podspec" spec="~> 0.1.3" /> -->
<!--包含本地需要說(shuō)明的文件或頭文件-->
<!-- <header-file src="src/ios/WechtSDK1.8.2/WechatAuthSDK.h" />
<header-file src="src/ios/WechtSDK1.8.2/WXApi.h" />
<header-file src="src/ios/WechtSDK1.8.2/WXApiObject.h" />
<header-file src="src/ios/WechtSDK1.8.2/README.txt" />
// 如果設(shè)置為true,則還將指定的文件作為框架添加到項(xiàng)目中。
<source-file src="src/ios/WechtSDK1.8.2/libWeChatSDK.a" framework="true" />
// 這類似于<source-file>元素,但專門針對(duì)iOS和Android等平臺(tái),用于區(qū)分源文件,頭文件和資源。
// 寫入xcode 中: copy bundle resource 中 一般為 xml bundle 文件
<resource-file src="src/ios/AlipaySDK.bundle" /> -->
<!--
.a 靜態(tài)庫(kù), 請(qǐng)往上看, 需要用 source-file
custom: 指示framework是否包含在插件文件中。也就是本地庫(kù), 如果是系統(tǒng)庫(kù)不需要 custom="true"
embed="true"需要配合custom="true"使用, 就是可以將你的動(dòng)態(tài)庫(kù)嵌入到應(yīng)用程序中, 但需要: cordova-ios@4.4.0 and cordova-cli@7.0.0 , 如果使用該屬性, 請(qǐng)?jiān)O(shè)置好 cordova-ios 版本.
<framework src="src/ios/OrderPlaceSDK.framework" custom="true" embed="true" />
<framework src="src/ios/iOS_ENETS_SDK_UAT/Alamofire.framework" custom="true" />
<framework src="src/ios/iOS_ENETS_SDK_UAT/Caishen.framework" custom="true" />
<framework src="src/ios/iOS_ENETS_SDK_UAT/CryptoSwift.framework" custom="true" />
<framework src="src/ios/iOS_ENETS_SDK_UAT/ENETSLib.framework" custom="true" />
<framework src="src/ios/iOS_ENETS_SDK_UAT/MBProgressHUD.framework" custom="true" />
<framework src="src/ios/iOS_ENETS_SDK_UAT/Presentr.framework" custom="true" />
<framework src="src/ios/iOS_ENETS_SDK_UAT/SwiftyJSON.framework" custom="true" />
-->
</platform>
</plugin>
到此我們的plugin.xml 就配置好了, 這里需要添加的文件就放到對(duì)應(yīng)的文件夾下面就可以
目前我的結(jié)構(gòu)類似這樣



- 其中 LICENSE ,是許可證, 可以用txt 文件寫一個(gè),不要后綴,名字是: LICENSE就可以.
- package.json 可以說(shuō)是配置文件吧.
- README.md , 可以寫上這個(gè)plugin 怎么用之類的, 如果上傳到gitHub , 它會(huì)插件的首頁(yè)顯示.
- src: 是放ios/android 原生代碼的地方
- www: 放的是js 文件
package.json
// version/ name/description, 與plugin.xml中保持一致
// repository, 是你放到gitHub 上的倉(cāng)庫(kù)
// bugs 是gitHub的issues 討論區(qū)
{
"version": "0.1.0",
"name": "cordova-plugin-netspay",
"cordova_name": "cordova-plugin-netspay",
"description": "cordova-plugin-netspay",
"license": "Apache 2.0",
"author": {
"name": "Joson",
"email": "xxxx@xxx.com"
},
"repository": {
"type": "git",
"url": "https://github.com/PeiJueChen/cordova-plugin-netspay.git"
},
"bugs": {
"url": "https://github.com/PeiJueChen/cordova-plugin-netspay.git/issues"
},
"keywords": [
"cordova",
"plugin",
"netspay"
]
}
js 文件怎么寫 , js 文件一般放在www 文件夾下, 這是規(guī)范
/**
*
* exec(callback, errorCallback, pluginName, actionName, argumentArray)
* callback 插件成功返回時(shí)調(diào)用,并將本機(jī)插件中的任何參數(shù)傳遞給它
* errorCallback在插件遇到錯(cuò)誤時(shí)調(diào)用。我們?cè)谏厦媸÷粤诉@一點(diǎn)
* pluginName 是本機(jī)端的插件類名稱。就是類名 (feature 下param 中的value , 它也要和原生代碼中的類名對(duì)上.)
* actionName 是我們將在本機(jī)方面執(zhí)行的操作。
* argumentArray 是傳遞給本機(jī)端的參數(shù)數(shù)組
*/
// prototype 屬於是為class 添加方法/屬於用到的
var exec = require('cordova/exec'),
cordova = require('cordova'),
// utils = require('cordova/utils'),
// 如果需要引用本地js, 已經(jīng)在Plugin.xml 中
// <js-module src="www/PositionError.js" name="PositionError">
// <clobbers target="PositionError" />
// </js-module>
//PositionError = require('./PositionError');
var NetsPay = (function () {
// var platformId = cordova.platformId; // 'android' 'ios'
function NetsPay() {
// console.log("platformId: " + platformId + code);
}
// 建議加上cordova調(diào)用, 因?yàn)橹蟮陌姹綾ordova 提示說(shuō)需要加cordova在前面調(diào)用
NetsPay.prototype.requestPay = function (echoValue, successCallback, errorCallback) {
cordova.exec(successCallback, errorCallback, 'NetsPay', 'requestPay', [echoValue]);
};
return NetsPay;
})();
var netsPay = new NetsPay();
// 導(dǎo)出屬性, 調(diào)試時(shí), window. 就會(huì)有提示這個(gè)屬性.
module.exports = netsPay;
下面看看 NetsPay 文件
- iOS
#import "NetsPay.h"
#import <Cordova/CDVPluginResult.h>
#import <ENETSLib/ENETSLib-Swift.h>
@interface NetsPay ()<PaymentRequestDelegate>
@property (strong, nonatomic) NSString* requestPayCallbackId;
@end
@implementation NetsPay
- (void)requestPay:(CDVInvokedUrlCommand*)command
{
NSString* callbackId = [command callbackId];
self.requestPayCallbackId = callbackId;
// do something
[self pay:command];
// 說(shuō)幾點(diǎn)注意的, 傳過(guò)來(lái)的參數(shù)可以根據(jù) [command.arguments objectAtIndex:0]; 索引拿到
// 想調(diào)用回調(diào)時(shí):
/*
CDVCommandStatus_OK , 這個(gè)值cordova 提供多種了,可以選擇
NSDictionaray *dict = @{@"key":@"value"};
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsDictionary:dict];
[self.commandDelegate pluginResult callbackId:command.callbackId];
*/
// 如果call back 是異步調(diào)用,要
// [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
}
*Android
package cordova.plugin.netspay;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class NetsPay extends CordovaPlugin {
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
if (action.equals("requestPay")) {
String message = args.getString(0);
this. requestPay(message, callbackContext);
return true;
}
return false;
}
private void requestPay(String message, CallbackContext callbackContext) {
if (message != null && message.length() > 0) {
callbackContext.success(message);
} else {
callbackContext.error("Expected one non-empty string argument.");
}
}
}
到此一個(gè)cordova plugin 就完成了
添加
- 建議先在本地使用, 因?yàn)楸镜匕惭b時(shí),如果寫得有問(wèn)題, 會(huì)安裝提示失敗及原因. 最后測(cè)試沒(méi)問(wèn)題再Push 到github .
-
可以把寫好plugin 放在與測(cè)試工程同一級(jí)下, 執(zhí)行:
cordova plugin add ../cordova-plugin-netspay(插件文件夾名, 要讓他能夠找到plugin.xml 文件)
如果你已經(jīng)push 到github 可以執(zhí)行
cordova plugin add github地址 --variable GEOLOCATION_USAGE_DESCRIPTION ="寫上你想在xcode info.plist文件中對(duì)應(yīng)key的value"
添加成功后.
使用
// cordova.plugins.netspay 這個(gè)名字是由
/*
<js-module src="www/netspay.js" name="netspay">
<clobbers target="cordova.plugins.netspay" />
</js-module>
clobbers中的target 來(lái)的
*/
try {
(<any>window).cordova.plugins.netspay.requestPay({"hmac": "hmacfdsff3424"},
(s) => {
console.log('callback requestPay success', s);
}, err => {
console.log('callback requestPay err', err);
})
} catch (exception) {
console.log(' open requestPay error ', exception);
}
到此, 我們的cordova plugin 就創(chuàng)建結(jié)束, 如果想看關(guān)于swift怎么創(chuàng)建cordova插件, 請(qǐng)看我的另一篇文章:創(chuàng)建swift 版本的 cordova 插件,它會(huì)多幾個(gè)注意點(diǎn), 其實(shí)就是語(yǔ)法不同導(dǎo)致的.
補(bǔ)允: 如果是app 的使用者, 想添加pod ,可以在config.xml 中做以下配置 , ref
<platform name="ios">
<!-- set platform :ios, defaults to 7.0 -->
<preference name="pods_ios_min_version" value="8.0"/>
<!-- add use_frameworks! to Podfile, this also disabled bridging headers -->
<preference name="pods_use_frameworks" value="true"/>
<!-- use the latest version of a pod -->
<pod name="LatestPod" />
<!-- use a specific version of a pod -->
<pod name="VersionedPod" version="1.0.0" />
<!-- use a custom repo -->
<pod name="GitPod1" git="https://github.com/blakgeek/something" tag="v1.0.1" />
<pod name="GitPod2" git="https://github.com/blakgeek/something" branch="wood" />
<pod name="GitPod3" git="https://github.com/blakgeek/something" commit="1b33368" />
<!-- target specific configurations, this can be combined with all other options -->
<pod name="GitPod2" configuration="debug" />
<pod name="GitPod2" configurations="release,debug" />
<!-- add a pod dependency using a custom podspec -->
<pod name="GitPod2" podspec="https://example.com/JSONKit.podspec" />
<!-- add a pod dependency using the spec parameter like a Cordova framework -->
<pod name="GitPod2" spec="~> 2.0.0"/>
<pod name="GitPod2" spec=":configurations => ['Debug', 'Beta']"/>
<!-- if pod uses a bundle that isn't compatible with Cocoapods 1.x -->
<pod name="BadBundle" fix-bundle-path="Bad/Path.bundle"/>
</platform>

