PS: Ionic 为什么要用Cordova插件?
先看下Ionic是什么?
Ionic(ionicframework)一款开源的Html5移动App开发框架,是以AngularJS为基础的移动端解决方案,Ionic以流行的跨平台移动app开发框架phoengap为蓝本,让开发者可以通过命令行工具快速生成android ios移动app应用。
phoengap又是什么?
PhoneGap是Apache Cordova最原始和最流行的分发,用基于HTML,CSS和JavaScript的,创建移动跨平台移动应用程序的快速开发平台。它使开发者能够利用iPhone,Android,Palm,Symbian,WP7,WP8,Bada和Blackberry智能手机的核心功能——包括地理定位,加速器,联系人,声音和振动。原本由Nitobi公司开发,在2011年10月4日,Adobe公司收购了这个Nitobe公司,后来Adobe把PhoneGap项目捐献给了Apache基金会。当2012年PhoneGap更新到1.4版本后,Apache又把名字更新成Cordova,有趣的是Cordova是PhoneGap团队附近一条街的名字。参考
Ionic/Angular和Cordova关系是?
可能会有人被问道:“Cordova比Ionic/Angular好吗?”,这就很尴尬了,根本是毫无意义的问题。它们在混合开发中扮演的是不同的角色–Ionic/Angular负责页面的实现,而Cordova负责将实现的页面包装成原生应用(Android:apk;iOS:ipa)。就像花生,最内层的花生仁是Angular,花生仁的表皮是Ionic,而最外层的花生壳则是Cordova。包装完成之后我们的页面才有可能调用设备的原生能力,最后才能上传到应用商店被用户使用。
关于Ionic使用Cordova插件:
Cordova插件的作用是提供一个桥梁供页面和原生通信,首先我们的页面不能直接调用设备能力,所以需要与能够调用设备能力的原生代码(Android:Java;iOS:OC)通信,此时就需要Cordova插件了。
Cordova插件能够再任何Cordova工程中使用,和使用什么前端框架(如Ionic)无关。
Ionic 2中封装了Ionic Native,方便了Cordova插件的使用,但在Ionic 2中仍然可以像Ionic 1中一样使用Cordova插件,Ionic Native不是必须的。
即使在Ionic 2中使用了Ionic Native,也首先需要手动添加插件,如:cordova plugin add cordova-plugin-pluginName。
了解这些概念之后,我们就可以愉快的创建一个cordova插件了,具体有这几个步骤:
安装插件管理脚手架:plugman
npm install -g plugman
创建插件:
plugman create --name 插件名称 --plugin_id 插件id --plugin_version 插件版本号 [--path ] [--variable NAME=VALUE]
参数说明:
pluginName: 插件名称,eg:toast
pluginID: 插件id, eg: org.my.toast
version: 版本号, eg: 0.0.1
variable NAME=VALUE: 扩展参数,如说明或者作者
例如:
plugman create --name helloPlugin --plugin_id helloPlugin --plugin_version 0.0.1
执行结果如图:
QQ20180729-151156@2x.png
为插件添加平台
添加android平台: plugman platform add --platform_name android
添加iOS平台:plugman platform add --platform_name ios
在www文件夹下生成了helloPlugin.js,helloPlugin.js的作用是通过js暴露插件的功能给插件使用者,helloPlugin.js文件如下:
exports.coolMethod = function (arg0, success, error) {
/**
* Cordova.exec()方法说明
* function(winParam) {}:成功回调函数。假设您的 exec成功完成,此功能将随您传递给它的任何参数一起执行
* function(error) {}:错误回调函数。如果操作未成功完成,则此功能将执行可选的错误参数
* "service":在本机端呼叫的服务名称,与原生端的类名保持一致
* "action":在本机端调用的动作名称,对应原生类execute()的入参,原生代码通过对action进行判断,从而知道JS让原生端执行什么样的功能,也就是执行的方法名
* [ arguments ]:传到原生环境的参数数组
*/
exec(success, error, 'helloPlugin', 'coolMethod', [arg0]);
};
android目录下生成的helloPlugin.java文件:
package helloPlugin;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
* This class echoes a string called from JavaScript.
*/
//自定义插件需要继承CordovaPlugin类,并且覆盖execute方法。
public class helloPlugin extends CordovaPlugin {
@Override
//参数action是用来判断执行哪个方法,args是json格式的参数,callbackContext响应返回结果。
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
if (action.equals("coolMethod")) {
String message = args.getString(0);
this.coolMethod(message, callbackContext);
return true;
}
return false;
}
//私有方法--调用的功能方法
private void coolMethod(String message, CallbackContext callbackContext) {
if (message != null && message.length() > 0) {
//成功回调
callbackContext.success(message);
} else {
//失败回调
callbackContext.error("Expected one non-empty string argument.");
}
}
}
插件配置文件:plugin.xml,关于plugin.xml的详细讲解请看这里
<?xml version='1.0' encoding='utf-8'?>
<plugin id="helloPlugin" version="0.0.1" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<name>helloPlugin</name>
<engines>
<engine name="cordova" version=">=8.0.0" />
<engine name="cordova-android" version=">=7.1.0" />
<engine name="cordova-ios" version=">=4.5.4" />
</engines>
<js-module name="helloPlugin" src="www/helloPlugin.js">
<clobbers target="helloPlugin" />
</js-module>
<platform name="ios">
<config-file parent="/*" target="config.xml">
<feature name="helloPlugin">
<param name="ios-package" value="helloPlugin" />
</feature>
<!-- 设置ALIpay 的scheme -->
<config-file target="*-Info.plist" parent="CFBundleURLTypes">
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>ALI$APP_ID</string>
</array>
</dict>
</array>
</config-file>
<preference name="APP_ID" value="$APP_ID" />
</config-file>
<!-- 申请权限设置:比如相机权限 -->
<config-file target="*-Info.plist" parent="NSCameraUsageDescription">
<string>我们的xxx功能想使用相机来为您提供更好的服务</string>
</config-file>
<!-- 插件源文件 -->
<source-file src="src/ios/TestPlugin.m" />
<!-- 插件依赖的iOS平台库 -->
<framework src="libz.dylib" />
<framework src="libc++.dylib" />
<framework src="libz.tbd" />
<framework src="Security.framework" weak="true" />
<framework src="VideoToolbox.framework" weak="true" />
<framework src="AVFoundation.framework" weak="true" />
<framework src="Contacts.framework" weak="true" />
<framework src="AddressBook.framework" weak="true" />
<framework src="AddressBookUI.framework" weak="true" />
<framework src="CoreTelephony.framework" weak="true" />
<framework src="CoreText.framework" weak="true" />
<framework src="QuartzCore.framework" weak="true" />
<framework src="CoreGraphics.framework" weak="true" />
<framework src="CoreMotion.framework" weak="true" />
<framework src="CFNetwork.framework" weak="true" />
<framework src="SystemConfiguration.framework" weak="true" />
<!-- 插件的功能实现文件:比如把插件的某个方法执行是打开TestViewController文件 -->
<header-file src="src/ios/TestViewController.h"/>
<source-file src="src/ios/TestViewController.m"/>
<!-- 插件依赖的第三方库,可以用pods管理,当插件被添加的时候,会自动帮iOS项目生成podfile文件,并自动install此处引用的框架, -->
<framework src="NIMKit" type="podspec" spec="~> 2.6.0" />
</platform>
<platform name="android">
<config-file parent="/*" target="res/xml/config.xml">
<feature name="helloPlugin">
<param name="android-package" value="helloPlugin" />
</feature>
</config-file>
<config-file parent="/*" target="AndroidManifest.xml">
</config-file>
<source-file src="src/android/helloPlugin.java" target-dir="src/com/plugin/helloPlugin/helloPlugin" />
</platform>
</plugin>
我们还需要一个package.json文件
npm init
执行结果:
QQ20180729-162256@2x.png
{
"name": "helloplugin",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
name等值可以自定义,也可以直接回车选择默认值。
ionic项目引用自定义插件
ionic cordova plugin add 你插件的存储路径
然后home.html文件中,添加btn click测试插件的方法有没有生效:
<ion-header>
<ion-navbar>
<ion-title>Home</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<h2>Welcome to Ionic!</h2>
<p>
This starter project comes with simple tabs-based layout for apps
that are going to primarily use a Tabbed UI.
</p>
<p>
Take a look at the <code>src/pages/</code> directory to add or change tabs,
update any existing page or create new pages.
</p>
<button ion-button (click)="testPlugin()">测试自定义插件</button>
</ion-content>
home.ts:
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
//定义cordova对象,注意,这个变量的定义,是个全局的引用,表示所有的插件对象都加载进来,我们的helloplugin插件也会被加载进来
declare let cordova: any;
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public navCtrl: NavController) {
}
testPlugin(){
// alert('testPlugin');
//引用自定义插件方法,具体插件类的调用需要看被调用插件的配置文件plugin.xml中的clobbers节点
helloplugin.coolMethod("插件测试!",result=>alert(result),error=>alert(error));
}
}
ionic项目真机、模拟器运行的命令简单列一下:
ionic cordova platform add ios/android //添加平台
ionic cordova emulate ios/android –lc //模拟器运行
ionic build ios/android //编译
ionic cordova run ios/android –lc //真机运行
修改自定义插件
比如修改android平台下的插件功能:
1.修改helloplugin/src/android/helloplugin.java文件,新增一个求和方法:
package helloPlugin;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
* This class echoes a string called from JavaScript.
*/
//自定义插件需要继承CordovaPlugin类,并且覆盖execute方法。
public class helloPlugin extends CordovaPlugin {
@Override
//参数action是用来判断执行哪个方法,args是json格式的参数,callbackContext响应返回结果。
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
if (action.equals("coolMethod")) {
String message = args.getString(0);
this.coolMethod(message, callbackContext);
return true;
}else if (action.equals("plus")) {//主方法中增加一段方法名称判断和调用的代码
int x = args.getInt(0);
int y = args.getInt(1);
this.plus(x, y, callbackContext);
return true;
}
return false;
}
//私有方法--调用的功能方法
private void coolMethod(String message, CallbackContext callbackContext) {
if (message != null && message.length() > 0) {
//成功回调
callbackContext.success(message);
} else {
//失败回调
callbackContext.error("Expected one non-empty string argument.");
}
}
//新增一个传入两个参数求和的方法
private void plus(int x, int y, CallbackContext callbackContext) {
callbackContext.success(x + y);
}
}
2.修改helloplugin/www/helloplugin.js代码
// var exec = require('cordova/exec');
// exports.coolMethod = function (arg0, success, error) {
// /**
// * Cordova.exec()方法说明
// * function(winParam) {}:成功回调函数。假设您的 exec成功完成,此功能将随您传递给它的任何参数一起执行
// * function(error) {}:错误回调函数。如果操作未成功完成,则此功能将执行可选的错误参数
// * "service":在本机端呼叫的服务名称,与原生端的类名保持一致
// * "action":在本机端调用的动作名称,对应原生类execute()的入参,原生代码通过对action进行判断,从而知道JS让原生端执行什么样的功能
// * [ arguments ]:传到原生环境的参数数组
// */
// exec(success, error, 'helloPlugin', 'coolMethod', [arg0]);
// };
var exec = require('cordova/exec');
var testAPI = {}
testAPI.coolMethod = function(arg0, success, error) {
exec(success, error, "helloPlugin", "coolMethod", [arg0]);
};
//求和方法
testAPI.plus = function(arg0,arg1, success, error) {
exec(success, error, "helloPlugin", "plus", [arg0,arg1]);
};
module.exports = testAPI;
3.修改自定义插件package.json和plugin.xml文件的版本号
4.自定义插件修改后必须先删除插件,然后再安装插件才可生效。
不知道自己的插件名字可以命令查看已安装的所有插件:
ionic cordova plugin list //列出所有已安装的插件
ionic cordova plugin remove helloPlugin //从ionic3项目中删除插件
ionic cordova plugin add 自定义插件路径 //安装插件到ionic3项目
以上4步就是插件的跟新步骤了~
到这里自定义插件及使用的方法就说完了,希望对您有所帮助~~~
插件配置文件详情请看:plugin.xml配置
参考文章
网友评论
This package is required for this command to work properly.
? Install @ionic/app-scripts? Yes
> npm i -D -E @ionic/app-scripts
npm WARN deprecated browserslist@2.11.3: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
npm WARN deprecated cryptiles@2.0.5: This version is no longer maintained. Please upgrade to the latest version.
npm WARN deprecated boom@2.10.1: This version is no longer maintained. Please upgrade to the latest version.
npm WARN deprecated hoek@2.16.3: This version is no longer maintained. Please upgrade to the latest version.
这个错误怎么回事啊,安装了也不行,大神,讲解一下