Plugins - In Depth Workshop
PhoneGap Day EU 2016
Jesse MacFadyen
http://purplecabbage.github.io/slides/pgd16Plugins/index.html
About Me
- PhoneGap Developer since 2008
- Apache Cordova committer
- at Adobe for nearly 5 years now
- @purplecabbage
Who has used cordova plugins?
- Everyone, you have to now.
- Since 3.0, ages ago!
Who understands how they work?
- Much less of us
- Let's fix that!
Install via npm
cordova plugin add cordova-plugin-device
cordova plugin ls
> cordova-plugin-device 1.1.1 "Device"
cordova plugin rm cordova-plugin-device
Install via repo url - github
cordova plugin add http://github.com/apache/cordova-plugin-device
cordova plugin ls
> cordova-plugin-device 1.1.1 "Device"
cordova plugin rm cordova-plugin-device
Install via local plugin
cordova plugin add Repos/cordova/cordova-plugin-device
cordova plugin ls
> cordova-plugin-device 1.1.1 "Device"
cordova plugin rm cordova-plugin-device
This is the recommended way for developing. With `--link`
Plugin Discovery
- https://cordova.apache.org/plugins/
- https://www.npmjs.com/search?q=ecosystem:cordova
The 'core' plugins
- battery-status
- camera
- console
- contacts
- device
- device-motion
- device-orientation
- dialogs
- file
- file-transfer
- geolocation
- globalization
- inappbrowser
- media
- media-capture
- network-information
- splash-screen
- status-bar
- vibration
- whitelist
- ... Am I missing any?
Plugin Authoring
plugin.xml defines your plugin
- a plugin id for registration discovery, add/rm
- a version number, author, repo, similar to package.json
- a list of platforms and native headers, source files, resources, javascript files
- configuration items, permission requirements
- js-modules - the js entry point for your plugin
- hooks
Who has used plugman?
- Everyone, but you may not even know you are.
- Plugman is a node lib that does the dirty work of managing plugins
- cordova-cli uses plugman under the hood
// npm install -g plugman
plugman install --plugin org.apache.cordova.device --platform wp8
--project .
## Plugman can also help you create your plugin
// try me!
plugman create --name PluginName --plugin_id jesse-plugin-id --plugin_version 0.0.1 --path .
Also accepts a --variable name=value pair string to define additional data like author, etc.
## Dependencies
- plugins can require other plugins too
```
//In plugin.xml
```
## Adding plugin functionality
exec(null, null, "StatusBar", "styleDefault", []); // JS
// in the app's (ios) config.xml
// in CDVStatusBar.m
- (void) styleDefault:(CDVInvokedUrlCommand*)command
{
[self setStyleForStatusBar:UIStatusBarStyleDefault];
}
## Sending Data Back to JS
```
// in CDVStatusBar.m
(void)fireTappedEvent
{
if (_eventsCallbackId == nil) { return; }
NSDictionary* payload = @{@"type": @"tap"};
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:payload];
[result setKeepCallbackAsBool:YES];
[self.commandDelegate sendPluginResult:result callbackId:_eventsCallbackId];
}
```
A walk through the iOS bridge
## Publishing your plugin
- npm is now the home of all core cordova plugins
- You'll need a package.json if you want to publish ...
## Plugman can do that too!
plugman createpackagejson path/to/my/plugin/
// show me!
npm publish
## What can plugins do?
- plugable, adds some functionality
- could be adding the functionality at runtime, build time, or install time
### Plugins at runtime
- providing a UI framework, or helper mvc frameworks
- exposing native functions
- provide hooks for QA, debug-logging
- analytics
### Plugins at build time
- transpile ES6 to js-now, typescript, coffee-script
- _is coffee-script still a thing?_
- SASS/less pre-processing
- image inlining / webpack
- could be doing analysis
- code coverage, linting, quality checks
### Plugins at install time
- could also bundle other plugins, a mashup
- could provide tests for another plugin
### A more complex plugin demo
phonegap-plugin-sidebar
This plugin includes a demo!
- Demo issue with statusbar and sidebar
### Note how that demo was installed!
the `--link` in the demo instructions was important
Plugin testing
cordova-medic is a test tool which is designed to run ALL the plugin tests
- tests are written in Jasmine 2.0
- tests run asyncronously
- plugins have a dependent test/ plugin which is installed separately
- by convention
cordova-plugin-device
Many of the pieces of cordova-medic are reusable, so I spun them into another purpose based tool
## cordova-paramedic
_provides advanced levels of care at the point of illness or injury, including out of hospital treatment, and diagnostic services_
cordova-paramedic --platform ios --plugin .
## automates jasmine test running
- creates a new project (in temp)
- adds the platform specified (ios|android|windows)
- installs the cordova-plugin-test-framework plugin
- installs the plugin specified
- installs the plugin's tests ( a plugin ... from the test/ folder )
- sets the start page to cordova-plugin-test-framework plugins test runner page
- creates a local server to listen for results posted back from the test runner
- exits with success/fail based on results
## Some caveats
- only supports npm published platforms
```
// this will not work currently!
cordova-paramedic --platform /Repos/cordova/cordova-ios --plugin .
```
## How to write tests
- copy a core plugin, really, it's what I do
- create a test/ folder in your plugin repo
- add a plugin.xml file
## Debugging Native Code in XCode
## Debugging Windows JS code in Visual Studio
( note to self: start your vm! )
## The Windows Bridge
- there isn't one
- js is a first class citizen
- windows exec uses a proxy
cordova-plugin-device
## Publishing your plugin
- `npm publish`
- shine! profit!
## Docs
- Of course you should include docs, so users know how to use your plugin
- Look at any of the 'core' plugins for best practices.
- English in the root README.md
- translations in the docs/ folder
## Hooks
Great guide here:
https://cordova.apache.org/docs/en/latest/guide/appdev/hooks/
A cool hook example here:
https://github.com/stevengill/es6-phonegap
## Homework
- Extend a plugin, remix it, remux it ex. The globalization plugin is async, which is really irritating.
https://github.com/apache/cordova-plugin-globalization
-- All formatting/globalization info could be fetched up front, and then processing could happen NSYNC
Questions?
twitter.com/purplecabbage
One more thing, or a few ...
- Some platforms support plugins that are separate projects
- Some plugins reference third party libraries.
- Cocoapod support is coming to iOS
- gradle support exists in Android, soon plugins can actually be AARs