Wednesday, November 30, 2016

Upcoming Conference Appearances

Next week I'll be in two European capitals.


I'll be at the following events:

If you are going to be at any of those events please introduce yourself to me so we can chat. Other than that I'll have limited time available in those two cities but I do love coffee so hit me up on twitter.

Sunday, July 10, 2016

PluginPub - Publish your PhoneGap plugins to NPM

I was inspired by Sindre Sorhus package np which makes publishing a package to npm easy by running the following tasks automatically for you:


  • Ensures you are publishing from the master branch
  • Ensures the working directory is clean and that there are no unpulled changes
  • Reinstalls dependencies to ensure your project works with the latest dependency tree
  • Runs the tests
  • Bumps the version in package.json and npm-shrinkwrap.json (if present) and creates a git tag
  • Publishes the new version to npm, optionally under a dist-tag
  • Pushes commits and tags to GitHub
Now I'm in favour of anything that makes my life easier so I decided to take np and enhance it with some tasks I routinely do when publishing new plugins. My first pass at it is a new package called pluginpub which is a copy of np that I eventually hope to change to depend on np instead. 

The main difference is that it:

  • Bumps the version in plugin.xml, package.json and npm-shrinkwrap.json (if present) and creates a git tag
It now automates a lot of stuff I used to do manually into a single command. Installation is simple, you run:

npm install pluginpub --save-dev
In the root of your plugin repo. Then to release a new version of the plugin you would execute the command from the root of your plugin repo:

pluginpub 1.5.8
The command takes only one argument and that is the version of the plugin. If you don't pass in a valid semver then the command will fail.

Anyway, it make or may not be of use to you. Feel free to try it out and report any issues on the github page. Next steps are publishing a proper README and adding the auto-generation of a CHANGELOG file which is another manual step I hate doing when releasing a plugin.

Monday, June 27, 2016

Using ES2015 Code in Your PhoneGap Plugins

Everyone loves the new hotness of ES2015 features but sadly not all of the devices your app is going to run on are able to take advantage of all the features of ES2015. Luckily we can use Babel to transpile our ES2015 code into ES5 code that will run everywhere. This way we can write our plugin's JS using the new hotness but still run everywhere.

I've started working on a version of the PhoneGap Push Plugin in the es6 branch that uses ES2015 and what follows is a description of how I set it up.

Step 1: Add the necessary packages to package.json

We need to add Babel to our package.json so open the file and add the following lines.

  "devDependencies": {
    "babel-cli": "^6.10.1",
    "babel-core": "^6.10.4",
    "babel-preset-es2015": "^6.9.0"
  }
Then run the command:

npm install

Step 2: Create a .babelrc file

We'll have to tell babel how we want the code transpiled from ES2015 to ES5. So create a new file called .babelrc in the root of your plugin project and populate it with the following lines:

{
  "presets": [
    "es2015"
  ]
}

Step 3: Write your ES2015 code

I like to add a new directory under the src folder called src/js. It is in this folder that I like to keep my ES2015 compliant code.

Step 4: Transpile your code

Once your ES2015 code is written it is time to transpile it to ES2015 so you can publish to NPM and Github. For this open package.json and add a new line to the scripts section:

  "scripts": {
    "build": "babel src/js --out-dir www",
  }
Now if you run the command:

npm run build
You will find your transpiled code in the www folder of your plugin.

Step 5: Link to the ES5 code in plugin.xml

It is key that you don't actually deliver the ES2015 code as part of the plugin as you want to make sure your users are executing the ES5 version. To do that open plugin.xml and make sure that your js-module tag refers to code in the www directory like:

<js-module name="PushNotification" src="www/push.js">
  <clobbers target="PushNotification">
</clobbers></js-module>
and not:
<js-module name="PushNotification" src="js/src/push.js">
  <clobbers target="PushNotification">
</clobbers></js-module>
Bonus Material

If you are anything like me, writing ES2015 code is not quite second nature yet. In order to help me along I setup my project to be linted automatically.

Step 1: Add the necessary packages to package.json

We need to add ESLint to our package.json so open the file and add the following lines.

  "devDependencies": {
    "babel-eslint": "^6.1.0",
    "eslint": "^2.13.1",
    "eslint-config-airbnb": "^9.0.1",
    "eslint-plugin-import": "^1.9.2",
    "eslint-plugin-jsx-a11y": "^1.5.3",
    "eslint-plugin-react": "^5.2.2"
  }
Then run the command:

npm install

Step 2: Create a .eslintrc file

We'll have to tell ESLint how we want the code linted. So create a new file called .eslintrc in the root of your plugin project and populate it with the following lines:

{
  "extends": "airbnb",
  "parser": "babel-eslint",
  "ecmaFeatures": {
    "experimentalObjectRestSpread": true
  },
  "rules": {
    "spaced-comment": 0,
    "no-console": 0,
    "no-unused-expressions": [2, { "allowShortCircuit": true }]
  },
  "env": {
      "node": true,
      "mocha": true,
      "browser": true
  }
}
Step 3: Setup Your Editor

Not sure what editor you are using to write JS but I'm using Atom at the moment so I have installed the linter-eslint package which automatically picks up my .eslintrc file and lints my code on the fly.

Happy ES2015 coding everyone!

Sunday, May 22, 2016

Apps Crashing with phonegap-plugin-push and Google Play Services 9.0.0

Late last week Google pushed a new version of Google Play Services out to phones and since them some users of the phonegap-plugin-push have been seeing crashes in their app. The stack trace for that crash looks like this:

05-22 16:21:42.868 10979 11117 E AndroidRuntime: java.lang.IncompatibleClassChangeError: The method 'java.io.File android.support.v4.content.ContextCompat.getNoBackupFilesDir(android.content.Context)' was expected to be of type virtual but instead was found to be of type direct (declaration of 'com.google.android.gms.iid.zzd' appears in /data/app/io.cordova.hellocordova-1/base.apk)
05-22 16:21:42.868 10979 11117 E AndroidRuntime: at com.google.android.gms.iid.zzd.zzeC(Unknown Source)
05-22 16:21:42.868 10979 11117 E AndroidRuntime: at com.google.android.gms.iid.zzd.(Unknown Source)
05-22 16:21:42.868 10979 11117 E AndroidRuntime: at com.google.android.gms.iid.zzd.(Unknown Source)
05-22 16:21:42.868 10979 11117 E AndroidRuntime: at com.google.android.gms.iid.InstanceID.zza(Unknown Source)
05-22 16:21:42.868 10979 11117 E AndroidRuntime: at com.google.android.gms.iid.InstanceID.getInstance(Unknown Source)
05-22 16:21:42.868 10979 11117 E AndroidRuntime: at com.adobe.phonegap.push.PushPlugin$1.run(PushPlugin.java:75)
05-22 16:21:42.868 10979 11117 E AndroidRuntime: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
05-22 16:21:42.868 10979 11117 E AndroidRuntime: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
05-22 16:21:42.868 10979 11117 E AndroidRuntime: at java.lang.Thread.run(Thread.java:818)
05-22 16:21:42.882  5060  6828 W ActivityManager:   Force finishing activity io.cordova.hellocordova/.MainActivity
The crash is being cause because of a incompatibility between the newly released Google Play Services and Android Support Library v4. The phonegap-plugin-push does not use Android Support Library v4 but another plugin in your app may. You can check by doing:
grep -r com.android.support plugins
To see which other plugin is using Android Support Library v4. Removing that plugin, recompile and reinstall the application fixes the problem. Obviously this is not a desired or long term fix. Trying to figure out a way to prevent this but I fear we will require a new version of Android Support Library v4 from Google.

Subscribe to the Issue #909 on the plugin's repo for more info and updates.

Monday, March 28, 2016

Cordova Magic Commands

I was inspired by the following tweet:

conjure = cordova create $1 $2 $3 ; cd $1
summon = cordova platform add $1
banish = cordova platform rm $1
enchant = cordova plugin add $1
curse = cordova plugin rm $1
mix = cordova build $1
cast = cordova run $1
spells = cordova platforms ; cordova plugins

You can see the commands in action in this terminal session recording:

To create my own set of magic commands for Cordova. You can grab the additions I put into my .bash_profile file from this gist.
There is no real good reason for this other than I giggle to myself everytime I enchant or curse a plugin.