创建插件
插件 是一个注入代码的包,它允许应用在其上呈现的 Cordova webview 与其运行的原生平台进行通信。插件提供了对基于 Web 的应用程序通常无法访问的设备和平台功能的访问。所有主要的 Cordova API 功能都作为插件实现,并且还有许多其他可用的插件,可以启用诸如条形码扫描仪、NFC 通信或定制日历界面之类的功能。您可以在 Cordova 插件搜索页面上搜索可用的插件。
插件包含一个单一的 JavaScript 接口以及每个支持平台的相应原生代码库。本质上,这将各种原生代码实现隐藏在一个通用的 JavaScript 接口后面。
本节将逐步介绍一个简单的 echo 插件,该插件将一个字符串从 JavaScript 传递到原生平台,然后再返回,您可以将其用作构建更复杂功能的模型。本节讨论基本的插件结构和面向外部的 JavaScript 接口。对于每个相应的原生接口,请参阅本节末尾的列表。
除了这些说明之外,在准备编写插件时,最好查看现有插件以获取指导。
构建插件
应用程序开发人员使用 CLI 的 plugin add 命令 将插件添加到项目中。该命令将包含插件代码的 git 存储库的 URL 作为参数。此示例实现了 Cordova 的 Device API
cordova plugin add https://github.com/apache/cordova-plugin-device
如果插件发布到 npm,该命令还可以接收包名称作为参数
cordova plugin add cordova-plugin-device
插件存储库必须具有顶级的 plugin.xml
清单文件。有很多方法可以配置此文件,详细信息可在 插件规范 中找到。
此简短版本的 Device
插件提供了一个简单的示例,可用作模型
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="https://apache.ac.cn/cordova/ns/plugins/1.0"
id="cordova-plugin-device" version="0.2.3">
<name>Device</name>
<description>Cordova Device Plugin</description>
<license>Apache 2.0</license>
<keywords>cordova,device</keywords>
<js-module src="www/device.js" name="device">
<clobbers target="device" />
</js-module>
<platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="Device">
<param name="ios-package" value="CDVDevice"/>
</feature>
</config-file>
<header-file src="src/ios/CDVDevice.h" />
<source-file src="src/ios/CDVDevice.m" />
</platform>
</plugin>
- 顶级
plugin
标签的id
属性通常遵循cordova-plugin-{插件名称}
模式,并与插件的 npm 包名称匹配。 js-module
标签指定 通用 JavaScript 接口 的路径。platform
标签指定一组相应的原生代码,在本例中为ios
平台。config-file
标签封装一个feature
标签,该标签被注入到特定于平台的config.xml
文件中,以使平台了解额外的代码库。header-file
和source-file
标签指定库的组件文件的路径。
JavaScript 接口
JavaScript 接口提供了面向前端的接口,使其可能成为插件最重要的部分。您可以随意构造插件的 JavaScript,但您需要调用 cordova.exec
与原生平台进行通信,使用以下语法
cordova.exec(function(winParam) {},
function(error) {},
"service",
"action",
["firstArgument", "secondArgument", 42, false]);
以下是每个参数的工作方式
-
function(winParam) {}
:一个成功回调函数。假设您的exec
调用成功完成,此函数将与您传递给它的任何参数一起执行。 -
function(error) {}
:一个错误回调函数。如果操作未成功完成,此函数将使用可选的错误参数执行。 -
"service"
:在原生端调用的服务名称。这对应于一个原生类,有关更多信息,请参见下面列出的原生指南。 -
"action"
:在原生端调用的操作名称。这通常对应于原生类方法。请参阅下面列出的原生指南。 -
[/* 参数 */]
:要传递到原生环境的参数数组。
示例 JavaScript
此示例展示了一种实现插件 JavaScript 接口的方法
window.echo = function(str, callback) {
cordova.exec(callback, function(err) {
callback('Nothing to echo.');
}, "Echo", "echo", [str]);
};
在此示例中,插件将其自身作为 echo
函数附加到 window
对象,插件用户将按以下方式调用该函数
window.echo("echome", function(echoValue) {
alert(echoValue == "echome"); // should alert true.
});
查看传递给 cordova.exec
函数的最后三个参数。第一个调用 Echo
服务,这是一个类名称。第二个请求 echo
操作,该类中的一个方法。第三个是包含 echo 字符串的参数数组,它是 window.echo
函数的第一个参数。
传递给 exec
的成功回调只是对 window.echo
的回调函数的引用。如果原生平台触发错误回调,它只会调用成功回调并向其传递一个默认字符串。
原生接口
一旦为插件定义了 JavaScript,就需要至少用一个原生实现来补充它。下面列出了每个平台的详细信息,每个平台都基于上面简单的 Echo 插件示例
在开发过程中测试插件
在开发过程中手动测试插件的最简单方法是像往常一样创建一个 Cordova 应用程序,并使用 --link
选项添加插件
cordova plugin add ../path/to/my/plugin/relative/to/project --link
这将创建一个符号链接而不是复制插件文件,这使您可以在插件上工作,然后只需重建应用程序即可使用您的更改。
使用 Plugman 验证插件
您可以使用 plugman
实用程序来检查插件是否为每个平台正确安装。使用以下 node 命令安装 plugman
npm install -g plugman
您需要一个有效的应用程序源目录,例如默认 CLI 生成的项目中包含的顶级 www
目录,如 创建您的第一个应用 指南中所述。
然后运行如下命令来测试 iOS 依赖项是否正确加载
plugman install --platform ios --project /path/to/my/project/www --plugin /path/to/my/plugin
有关 plugman
选项的详细信息,请参阅 使用 Plugman 管理插件。有关如何实际 调试 插件的信息,请参阅 上面列出的每个平台的原生接口。
发布插件
您可以将插件发布到任何基于 npmjs
的注册表,但推荐的注册表是 npm 注册表。其他开发人员可以使用 plugman
或 Cordova CLI 自动安装您的插件。
要将插件发布到 npm,您需要按照以下步骤操作
-
安装
plugman
CLI$ npm install -g plugman
-
为您的插件创建一个
package.json
文件$ plugman createpackagejson /path/to/your/plugin
-
发布它
$ npm adduser # that is if you don't have an account yet $ npm publish /path/to/your/plugin
有关 npm 用法的更多详细信息,请参阅 npm 文档站点上的 发布 npm 包。
与插件搜索集成
要在 Cordova 插件搜索 中显示插件,请在发布之前将 ecosystem:cordova
关键字添加到插件的 package.json
文件中。
要指示对特定平台的支持,请在 package.json
的关键字列表中添加 cordova-<platformName>
格式的关键字。Plugman 的 createpackagejson
命令会为您执行此操作,但是如果您没有使用它来生成 package.json
,则应手动对其进行编辑,如下所示。
例如,对于支持 Android 和 iOS 的插件,package.json
中的关键字应包括
"keywords": [
"ecosystem:cordova",
"cordova-android",
"cordova-ios"
]
有关 package.json 的更详细示例,请查看 cordova-plugin-device 的 package.json 文件。
指定 Cordova 依赖项
Cordova 6.1.0 添加了支持,用于将插件的 Cordova 相关依赖项指定为插件 package.json
文件的一部分。插件可以列出多个版本的依赖项,以便在 Cordova CLI 从 npm 中选择要获取的插件版本时为它提供指导。CLI 将选择与本地项目已安装的平台和插件以及本地 Cordova CLI 版本兼容的最新插件版本。如果没有插件的版本兼容,CLI 将警告用户有关失败的要求,并回退到获取最新版本的旧行为。
此功能旨在最终取代 plugin.xml 中的 engines 元素。列出依赖项是确保您的插件从 npm 获取时不会出现损坏或导致构建错误的好方法。如果插件的最新版本与项目不兼容,CLI 将会向应用开发者提供一份未满足的项目需求列表,以便他们了解不兼容性并更新项目以支持您的插件。这允许您的插件在不让那些针对旧平台和插件进行构建的开发者感到困惑的情况下,响应重大更改。
要为插件指定与 Cordova 相关的依赖项,请修改 package.json
中的 engines
元素,使其包含一个具有以下结构的 cordovaDependencies
对象
"engines": {
"cordovaDependencies": {
PLUGIN_VERSION: {
DEPENDENCY: SEMVER_RANGE,
DEPENDENCY: SEMVER_RANGE,
...
},
...
}
}
PLUGIN_VERSION
指定您的插件的版本。它应该遵循 npm 的 semver 包定义的单个版本的语法,或上限(请参阅下文)DEPENDENCY
可以是以下之一- Cordova CLI:
"cordova"
- Cordova 平台:
"cordova-android"
、"cordova-ios"
等。 - 另一个 Cordova 插件:
"cordova-plugin-camera"
等。
- Cordova CLI:
SEMVER_RANGE
应遵循 npm 的 semver 包定义的范围语法
注意:Cordova 平台 DEPENDENCY
指的是 Cordova 平台,而不是操作系统,例如 cordova-android
而不是 Android 操作系统。
您的 cordovaDependencies
可以列出任意数量的 PLUGIN_VERSION
要求和任意数量的 DEPENDENCY
约束。未列出依赖项的插件版本将被假定为具有与其下方列出的最高 PLUGIN_VERSION
相同的依赖项信息。例如,考虑以下条目
"engines": {
"cordovaDependencies": {
"1.0.0": { "cordova-android": "<3.0.0"},
"2.1.0": { "cordova-android": ">4.0.0"}
}
}
低于最低条目(在此示例中为 1.0.0)的所有插件版本都被假定为没有依赖项。1.0.0 和 2.1.0 之间的任何插件版本都被假定为具有与 1.0.0 版本相同的依赖项(cordova-android 版本小于 3.0.0)。这使您仅在出现重大更改时才需要更新您的 cordovaDependencies
信息。
上限
除了单个版本外,cordovaDependencies
中的 PLUGIN_VERSION
还可以指定上限,以修改您的插件的旧版本的条目。当 DEPENDENCY
中发生重大更改,并且必须为所有不支持它的插件旧版本添加新约束时,这非常有用。这些上限应写为 <
,后跟一个 semver 版本(不是任意范围!)。这将把给定的任何 DEPENDENCY
值应用于指定版本以下的所有插件版本。例如,考虑以下条目
"engines": {
"cordovaDependencies": {
"0.0.1": { "cordova-ios": ">1.0.0" },
"<1.0.0": { "cordova-ios": "<2.0.0" },
"<2.0.0": { "cordova-ios": "<5.0.0" }
}
}
在这里,我们指定一个插件版本 (0.0.1) 和两个上限(<1.0.0 和 <2.0.0),它们约束 cordova-ios。这两个上限不会覆盖 0.0.1 的约束,它们会在评估时通过 AND 组合。当 CLI 检查项目的 cordova-ios 版本时,将针对插件版本 0.0.1 评估的约束将是这三个约束的组合
cordova-ios >1.0.0 AND cordova-ios <2.0.0 AND cordova-ios <5.0.0
请注意,只允许使用单个版本或上限作为 PLUGIN_VERSION
值;不支持其他 semver 范围。