preface

Recently, while working on a custom plug-in API for Angular projects to implement Cordova plug-in calls, I found that there were few Angular articles on custom plug-in API development available in the web tutorials. Then I realized that I could use the @ionic-native plug-in code structure as a reference, so I impersonated it. Made a simple scaffolding, and then toss about a weekend to finally get out, the process is still a song has a fold, so send a record to share

1 introduction

In this paper, we will explain in detail the creation, writing and release process of Cordova plugin to the custom @ionic-native/plugin, as well as the scaffolding development and release process of custom ionic-native. And how to fetch the Cordova plugin in an Angular project by calling the custom @ionic-native/plugin.

2 Cordova plug-in development

2.1 Create a Cordova project

Be sure to install Cordova before creating it

cordova create CordovaProject io.cordova.hellocordova CordovaApp
CordovaProject is the name of the directory to create the application. Io.cordova. Hellocordova is the default reverse field value. If possible, you should use your own field values. Cordovaapp is the title of your app.

I created Cordovaproject under jobProject

$cordova create CordovaProject com.ths.ll

2.2 Installation depends on PlugMan

Plugman is a command-line tool for installing and uninstalling plug-ins for Apache Cordova projects. Go to the CordovaProject project directory and install PlugMan

$ cd ./CordovaProjectPlugins
$ npm install -g plugman

2.3 Creating Plug-ins

2.3.1 Create a simple Toast plugin

Plugman create --name --plugin_id --plugin_version

To facilitate administration, create the plug-in in the Plugins folder under the Cordova project directory

$CD plugins $plugman create --name ThsToast --plugin_id cordova-ths-toast --plugin_version 1.0.0



Then manually rename the ThsToast directory to the value in the plugin_id above, cordova-plugin-ths-toast. Ths here and above represent the company’s common plug-in development prefix, which is usually an English string

Go to the plug-in directory and add the platform environment supported by the plug-in

$ cd cordova-plugin-ths-toast
$ plugman platform add --platform_name android
$ plugman platform add --platform_name ios

After adding it, two directories, Android and iOS, will be generated under the cordova-plugin-ths-toast directory. Here, only the ThsToast of the Android environment is defined. The generated file contents are shown in the figure



Note: Do not use names that conflict with Android native methods. For example, if Thstoast is changed to Toast, it will have the same name as the Toast class in Android.Widget.Toast, resulting in a build error



2.3.2 Plug-in configuration

After adding the platform, the plugin.xml file under the cordova-plugin-ths-toast directory will add the following



Modify the plugin.xml file as follows

<? The XML version = '1.0' encoding = "utf-8"? > < plugin id = "cordova - plugin - TSH - toast" version = "1.0.0" XMLNS = "http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android"> <name>Toast</name> <js-module name="ThsToast" src="www/ThsToast.js"> <! > <clobbers target="ThsToast" /> </js-module> <platform name="android"> <config-file parent="/*" target="res/xml/config.xml"> <feature name="ThsToast"> <! - the param value changes - > < param name = "android - package" value = ". Org. Apache cordova. Thstoast. Thstoast "/ > < / feature > </config-file> <config-file parent="/*" target="AndroidManifest.xml" /> <! -- target -- dir changes -- -- > < source - the file SRC = "SRC/android/ThsToast. Java" target - dir = "SRC/org/apache/cordova/ThsToast" / > </platform> <platform name="ios"> <config-file parent="/*" target="config.xml"> <feature name="ThsToast"> <param name="ios-package" value="ThsToast" /> </feature> </config-file> <source-file src="src/ios/ThsToast.m" /> </platform> </plugin>

Modify WWW/thstoast.js where, by the way, the exec method is the original method used to call the Cordova plugin, passing ‘ThsToast’,’show’ and [arg0], Java class name, action, and args, CallbackContext.success, CallbackContext.error





Modify the android/ thstoast.java file,

2.3.3 Initialize the plug-in

npm init

When prompted, enter the name of the plug-in ID, and fill in the rest according to the prompt. If it is not clear, press Enter to End, and a package.json file will be created

{"name": "cordova-plugin-ths-toast", "version": "1.0.0", "description": "show toast", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { "type": "git", "url": "git+https://github.com/qtpalmtop/cordova-plugin-ths-toast.git" }, "author": "lilin", "license": "ISC", "bugs": { "url": "https://github.com/qtpalmtop/cordova-plugin-ths-toast/issues" }, "homepage": "https://github.com/qtpalmtop/cordova-plugin-ths-toast#readme" }

Then modify package.json. Keywords keyword configuration is to display the plug-in in the Cordova Plugin Search. Engines configuration is to list the dependencies of multiple distributions. To guide the Cordova CLI in choosing the plug-in version to get from NPM, with the aim of eventually replacing the engine element in plugin.xml. Refer to the Cordova Create Plug-in for details

{"name": "cordova-plugin-ths-toast", "version": "1.0.0", "description": "show toast", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { "type": "git", "url": "git+https://github.com/qtpalmtop/cordova-plugin-ths-toast.git" }, "author": "lilin", "license": "ISC", "bugs": { "url": "https://github.com/qtpalmtop/cordova-plugin-ths-toast/issues" }, "homepage": "https://github.com/qtpalmtop/cordova-plugin-ths-toast#readme", "keywords": ["ecosystem:cordova", "cordova-Android "," cordova-iOS "], "Engines ": {"cordovaDependencies": {"2.0.0": {" cordova - android ":" > = 3.6.0 "}, "4.0.0" : {" cordova - android ":" > = 3.6.0 ", "cordova - Windows" : "> = 4.4.0"}, "6.0.0" : {"cordova": ">100"}}, "node": ">=6.0.0"}}

2.3.4 Publish the plug-in

Cordova plugin add cordova-plugin-ths-toast is used in a project using thstoast.show (), but to use it in an Angular project we need to develop a custom plugin API. Now let’s begin the development of Ionic Native API module

cd cordova-plugin-ths-toast
npm login
npm publish

3. Create Ionic Native plug-in

As those of you who have used the @ionic-native library will know, the @ionic-native library can be imported directly into an Angular project and is very convenient to use by simply importing the API in app.module.ts

// app.module.ts import { SplashScreen } from '@ionic-native/splash-screen/ngx'; @NgModule({ ... , providers: [ ..., SplashScreen ] })

Then import the SDK in the module you use to invoke the Cordova plug-in functionality directly

// app.component.ts import { SplashScreen } from '@ionic-native/splash-screen/ngx'; export class AppComponent { constructor( private splashScreen: SplashScreen ) { this.splashScreen.hide(); }}

So how do you create a plug-in like the @Ionic – Native library?

3.1 @Ionic – Native plug-in code disassembly

First we will install @ionic-native/splash-screen

npm install @ionic-native/splash-screen

You can see the plug-in structure as follows



index.js

Analysis: The __extends function inherits. The argument object on the left inherits the object on the right. SplashScreenOriginal creates a new function, SplashScreenOriginal. __extends(SplashScreenOriginal, _super) extends the IonicNativePlugin. This extends the IonicNativePlugin. This extends the IonicNativePlugin. Finally, export an instance of SplashScreenOriginal SplashScreen for us to call

var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; }) (); import { IonicNativePlugin, cordova } from '@ionic-native/core'; var SplashScreenOriginal = /** @class */ (function (_super) { __extends(SplashScreenOriginal, _super); function SplashScreenOriginal() { return _super ! == null && _super.apply(this, arguments) || this; } SplashScreenOriginal.prototype.show = function () { return cordova(this, "show", { "sync": true }, arguments); }; SplashScreenOriginal.prototype.hide = function () { return cordova(this, "hide", { "sync": true }, arguments); }; SplashScreenOriginal.pluginName = "SplashScreen"; SplashScreenOriginal.plugin = "cordova-plugin-splashscreen"; SplashScreenOriginal.pluginRef = "navigator.splashscreen"; SplashScreenOriginal.repo = "https://github.com/apache/cordova-plugin-splashscreen"; SplashScreenOriginal.platforms = ["Amazon Fire OS", "Android", "iOS", "Windows"]; return SplashScreenOriginal; }(IonicNativePlugin)); var SplashScreen = new SplashScreenOriginal(); export { SplashScreen };

Index.d.ts specifies object properties and methods

import { IonicNativePlugin } from '@ionic-native/core';
/**
 * @name Splash Screen
 * @description This plugin displays and hides a splash screen during application launch. The methods below allows showing and hiding the splashscreen after the app has loaded.
 * @usage
 * ```typescript
 * import { SplashScreen } from '@ionic-native/splash-screen/ngx';
 *
 * constructor(private splashScreen: SplashScreen) { }
 *
 * ...
 *
 * this.splashScreen.show();
 *
 * this.splashScreen.hide();
 * ```
 */
export declare class SplashScreenOriginal extends IonicNativePlugin {
    /**
     * Shows the splashscreen
     */
    show(): void;
    /**
     * Hides the splashscreen
     */
    hide(): void;
}

export declare const SplashScreen: SplashScreenOriginal;

The above code exports a generic instance that can call the plug-in, but to use it in Angular, you’ll have to look at the NGX code

For NGX /index.js, there is an __class property on the instance after the method is called. This property allows the instance to be injected into Angular as an Injectable method

@Injectable({
    providedIn: "root"
})

Before the call __decorate



After the call __decorate

var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; }) (); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { Injectable } from '@angular/core'; import { IonicNativePlugin, cordova } from '@ionic-native/core'; var SplashScreen = /** @class */ (function (_super) { __extends(SplashScreen, _super); function SplashScreen() { return _super ! == null && _super.apply(this, arguments) || this; } SplashScreen.prototype.show = function () { return cordova(this, "show", { "sync": true }, arguments); }; SplashScreen.prototype.hide = function () { return cordova(this, "hide", { "sync": true }, arguments); }; SplashScreen.pluginName = "SplashScreen"; SplashScreen.plugin = "cordova-plugin-splashscreen"; SplashScreen.pluginRef = "navigator.splashscreen"; SplashScreen.repo = "https://github.com/apache/cordova-plugin-splashscreen"; SplashScreen.platforms = ["Amazon Fire OS", "Android", "iOS", "Windows"]; SplashScreen = __decorate([ Injectable() ], SplashScreen); return SplashScreen; }(IonicNativePlugin)); export { SplashScreen };

There is little difference between the NGX /index.d.ts type specification and index.d.ts

import { IonicNativePlugin } from '@ionic-native/core';
/**
 * @name Splash Screen
 * @description This plugin displays and hides a splash screen during application launch. The methods below allows showing and hiding the splashscreen after the app has loaded.
 * @usage
 * ```typescript
 * import { SplashScreen } from '@ionic-native/splash-screen/ngx';
 *
 * constructor(private splashScreen: SplashScreen) { }
 *
 * ...
 *
 * this.splashScreen.show();
 *
 * this.splashScreen.hide();
 * ```
 */
export declare class SplashScreen extends IonicNativePlugin {
    /**
     * Shows the splashscreen
     */
    show(): void;
    /**
     * Hide the splashscreen
     */
    hide(): void;
}

package.json The attributes we need are author, dependencies, description, license, module entry, name plug-in name, PeerDependencies peerDependencies, repository address, and typi NGS type specification, version plug-in version number

{" _args ": [[" @ ionic - native/[email protected]", "/ Users/linli/jobProjects/ionic - presents - demo"]], "_from" : "@ionic-native/[email protected]", "_id": "@ionic-native/ int ", "_inBundle": false, "_integrity": "@ionic-native/[email protected]", "_id": "@ionic-native/ int ", "_inBundle": false, "_integrity": "sha512-6IhAEtVBf8lE7HdLgs+GLm83z9ukfdSwbKS9oMciJe8dpXTY3J2B2Fy8HgXpo88phccHXny1acEpFndns3oEkA==", "_location": "/@ionic-native/splash-screen", "_phantomChildren": {}, "_requested": { "type": "version", "registry": true, "raw": "@ ionic - native/[email protected]", "name" : "@ ionic - native/splash - screen", "escapedName" : "@ionic-native%2fsplash-screen", "scope": "@ionic-native", "rawSpec": "5.9.0", "savesSpec ": null, "fetchSpec": "5.9.0"}, "_requiredBy": ["/"], "_resolved": "Https://registry.npmjs.org/@ionic-native/splash-screen/-/splash-screen-5.9.0.tgz", "_spec" : "5.9.0", "_where" : "/Users/linli/jobProjects/ionic-angular-demo", "author": { "name": "ionic" }, "bugs": { "url": "https://github.com/ionic-team/ionic-native/issues" }, "dependencies": { "@types/cordova": "latest" }, "description": "Ionic Native - Native plugins for ionic apps", "homepage": "https://github.com/ionic-team/ionic-native#readme", "license": "MIT", "module": "index.js", "name": "@ ionic -- native/splash screen", "peerDependencies" : {" RXJS ":" ^ 5.5.0 | | ^ 6.5.0 ", "@ ionic - native/core" : "^ 5.1.0"}, "repository" : {" type ":" git ", "url" : "git+https://github.com/ionic-team/ionic-native.git}", "typings" : "The index which s", "version" : "5.9.0}"

3.2 Using THS-CLI scaffolding, Ionic – Native plug-in was generated

After analyzing the @ionic-native plug-in construction, let’s now use scaffolding to generate the structure of the above plug-in. Ths-cli is a scaffold I wrote for the company — >ths-cli< — Currently only the create-ionic-native command allows you to create @ionic-native plug-ins for Angular projects in the following way

// Ths-cli2 NPM install ths-cli2-g. Install ths-cli2-g

use

ths-cli create-ionic-native ths-native-toast
Usage: ths-cli <command> [project name] Options: -V, --version output the version number -h, --help display help for command Commands: Help [command] display help for command

Create-ionic-native represents the instruction to create an ionic-native plug-in

Ths-native-toast represents the name of the plug-in you want to generate

To demonstrate, the colon is followed by manual input, where the Cordova ID needs to be the same as the name of the Cordova plug-in described above

Ths-cli create-ionic-native Ths-native-toast > is downloading the project template. [email protected]: qtpalmtop/templates - ionic - native. According to the master > (ThsPlugin) : the name of the plugin ThsToast > plug-in id (TSH - native - plugin) : The cordova plugin ID (cordova-plugin-ths-pluginname) for 1.0.0 > : A plugin in named ThsPlugin: cordova-ths-toast > Show toast > plug-in git address (https://github.com/apache/cordova-plugin-ths-pluginName) : https://github.com/qtpalmtop/cordova-plugin-ths-toast is initialized project template: TSH - native - toast ✔ create success:)



When finished, the created Ths-Native-Toast plug-in will appear in the current directory



As can be seen from NGX /index.js, its structure is exactly the same as that of the @ionic-native plug-in, which can be used as the @ionic-native plug-in



Release the plugin

cd ths-native-toast
npm publish

You can then import the plugin in app.module.ts in your Angular project by NPM install ths-native-toast

Calling a custom plug-in in an Angular project

app.module.ts

import { ThsToast } from 'ths-native-toast/ngx'; @NgModule({ ... , providers: [ ThsToast ] })

app.component.ts

import {ThsToast} from 'ths-native-toast/ngx'; Constructor (private ThToast: ThToast) {this.Toast () {constructor() {this.Toast (); void { this.thsToast.show('hello world', () => { console.log('call toast success'); }, (error) => { console.log('call toast error'); }); }

APP real machine operation effect



Console printout

call toast success

5 concludes

Create Cordova plugman

2. Create Ionic Native plug-in (THS-CLI)

Import the Cordova and Ionic Native plug-ins into your Angular project

References:

Node.js based scaffolding tool development experience

Cordova custom plug-in development

NodeJS official documentation

If you have any questions or corrections, welcome to leave a message in the comment area, meet is fate, if you think this article is helpful to you, might as well point a like to encourage the next hey hey