Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Meetup: Custom Cordova Plugins for iOS and Android

Meetup: Custom Cordova Plugins for iOS and Android

Avatar for Andy White

Andy White

May 16, 2014
Tweet

Other Decks in Programming

Transcript

  1. Cordova: Custom Plugins for iOS and Android Andy White Pellucid

    Analytics ! Monday, May 19th, 2014 Full Stack Boulder: Sampling the Stack #2
  2. What is Cordova? • “Apache Cordova is a platform for

    building native mobile applications using HTML, CSS and JavaScript” • Write your applications in HTML, JavaScript, and CSS, and leverage native device services and code via a plugin API. • http://cordova.apache.org
  3. History of Cordova • Originally developed by a company called

    “Nitobi” with the name “PhoneGap” • Adobe acquired Nitobi, and the project was open- sourced and contributed to the Apache Software Foundation under the name “Apache Callback,” which was later changed to “Apache Cordova.” • Adobe now distributes a version of Apache Cordova under the name “PhoneGap,” and offers some additional related services (PhoneGap Build), but the underlying code is Apache Cordova. • http://phonegap.com/
  4. Getting Started • Newer versions support a node/npm-based CLI: npm

    install -g cordova • The cordova package gives you the “cordova” command, which is used for creating projects, building, running, etc. • Older versions of Cordova had different setup routines - see documentation for details. • You can also set it up manual
  5. Cordova CLI # create the project cordova create hello com.example.hello

    HelloWorld # hello = folder name (will be created at cwd) # com.example.hello = reverse DNS-style identifier # HelloWorld = app name ! # get into the project folder cd hello ! # add the desired platforms (for cross-platform app creation) cordova platform add ios # requires Xcode/etc. cordova platform add android # requires Android SDK/etc. ! # build the project cordova build ! # test the apps cordova emulate ios # run the app in iOS simulator cordova emulate android # run in Android emulator
  6. Built-In Plugins Device Info Battery Status Network Status Accelerometer Compass

    Geolocation Camera Video/Media Capture File Access Vibration Contacts etc.
  7. Adding a Plugin # search for plugins in the registry

    cordova plugin search [ text ] ! # add plugins from the registry cordova plugin add org.apache.cordova.device cordova plugin add org.apache.cordova.camera ! # add other plugins cordova plugin add https://github.com/apache/ cordova-plugin-console.git ! # show currently-installed plugins cordova plugin ls
  8. Using a Plugin: Camera Cordova plugins use a callback-based API.

    Most plugins are invoked via custom objects added to the window.navigator object, but others are event-based, or use other mechanisms. JavaScript code: ! navigator.camera.getPicture( function(result) { /* do something */ }, function(error) { /* do something with error */ }, { /* options */ });
  9. Building a Custom Plugin Cordova JavaScript API for invoking plugin:

    “service” = the name of the native component (e.g. class) “action” = the name of the method to invoke [“firstArgument”, …] = array of arguments to pass to plugin (can be nested arrays, object, primitives, etc.)
  10. iOS Native (Obj-C) Code • Create a class that inherits

    from “CDVPlugin” • Implement methods that return (void) and take an argument of (CDVInvokedUrlCommand *) • - (void)myPluginMethod:(CDVInvokedUrlCommand *)command; • Access plugin arguments via command.arguments • JS “primitives” are converted to equivalent native data types (JS string -> NSNumber, etc.) • JavaScript array <-> NSArray/etc. • JavaScript object -> NSDictionary/etc.
  11. Android Native (Java) Code • Create a class that extends

    “CordovaPlugin” • @Override the “execute” method to invoke plugin methods • @Override public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException • The action parameter is the “action” string passed from the JS code - use this to call a specific method (or just handle the call directly if your class only has one method) • The “execute” method should return true if you have a method for the action, or false if not. Errors should be propagated via the callbackContext, not the return value for execute.
  12. Why Custom Plugins? • Proxy network calls (if you can’t

    use AJAX in the web app - proxy the call through the native code) • Native data storage (access a client database via native code, using a JS plugin API) • Encryption (slow, difficult in JavaScript) • Custom business logic/algorithms • Offline app use (data storage, store-and-forward)
  13. Plugin Good Practices • Make sure your plugin is registered

    in the Cordova “config.xml” • Always put a try/catch at the top-level of your plugin method. An unhandled exception in your plugin method may crash or hang the app. • Do not swallow native exceptions - always propagate the error back to the JS code via the callback context “send error plugin result”. Let the JS code decide what to do with errors, not the native code. • If you see try/catch with an “e.printStackTrace()” in your Android code, you’ve got a problem. • The Cordova plugin API allows you to pass an array of items as a plugin argument. Avoid passing bare primitives as plugin arguments and results, unless that’s all you’ll ever need. Rather than passing an array of primitives, pass a single object argument, with keyed arguments. It makes the code easier to write and maintain on the native side, and allows your plugin to be modified/ extended more easily. • Not this: [“my first arg”, 2, false, “another arg”] • This: [{ message: “my first arg”, count: 2, isSpecial: false, errorMessage: “another” }]
  14. Plugin Good Practices (cont.) • Keep your plugins simple -

    each plugin method should only do one thing. Build a collection of plugins that can be combined via JavaScript to accomplish a bigger task. • Keep the application logic in JavaScript, not native code. • Put cordova.exec behind a layer of abstraction, with a stub implementation (or equivalent implementation) for running outside of Cordova land. (In other words, don’t call cordova.exec directly from your code, hide it). • Change the callback.exec callback API into a promise-based API (resolve a promise in the success callback, reject it in the failure callback). Avoid the callback “Pyramid of Doom!”
  15. Cordova Gotchas • Fast & frequent release cycle - fixes

    for issues introduced in newer devices/OS releases. • Cordova app upgrades not always trivial (Cordova 2->3 upgrade more painful) • Device differences, quirks, browser feature support • Browser churn, regressions, missing/buggy/incomplete HTML5 support, etc. (see: Android) • The UX for Cordova apps is sometimes not as smooth and seamless as native apps (gestures, button hitboxes, etc.) • However, Cordova apps are basically cross-platform (assuming the necessary plugins exist on all platforms)