Wednesday, December 13, 2017

Lose the head – Tag!

OutSystems 10 brought the wonderful world of low code to mobile application development. Now, it's about your ideas! Want an app to take pictures? Just "drive" to OutSystems Forge and look for the Camera Plugin and use it in your app:

OutSystems Camera Plugin

There are literally hundreds of plugins out there to interact with basically everything on your device, from accelerometer to camera, GPS, etc. OutSystems has a list of supported plugins, which means that not only you get official support if anything is wrong but the plugin is also properly maintained and evolved. However, the great power of this plugin mechanism is that the community is able to develop whatever plugin. Anything! Hey, I've created a plugin to keep the Android screen alive all the time. There's documentation on how to create a plugin, but I want to highlight a critical aspect of plugins.

OutSystems mobile apps are cordova based. This means that, potentially, any cordova plugin can be used in your apps ("potentially" because some plugins might not work - e.g.: because they are built for Android 2.3 (low target SDK), they don't have iOS implementation, etc). Lets head back to the Camera Plugin. To use it, you have a client action, "TakePicture". But what does that mean? Taking a picture is something that implies specific native iOS and Android commands. So, how is that client action doing the magic? Well, an OutSystems mobile plugin is actually composed by two distinct parts:

OutSystems Cordova

How does everything work together? Where's the glue? A bit more low level:

OutSystems Cordova

Looking at the image, you can see where the logic separation is between OutSystems and the native code. A cordova plugin basically exposes a Javascript API that OutSystems plugins ultimately call. There's still a missing piece: how does the platform know what cordova plugin you want?

OutSystems Cordova

It's in the OutSystems plugin extensibility configurations.

OutSystems Cordova

The camera plugin uses an URL to refer to the native part. When you request a native build of your mobile app the OutSystems Mobile Apps Build Service (MABS) will then use that URL to fetch the code for the native part of the code and include in the build of your app.

OutSystems Cordova

Now, here's the detail: did you notice the URL of the plugin?

It contains a what is called a tag (or release). This instructs the MABS to get that specific version of the plugin and not the latest and greatest. This is a best practice: do not use the head of the master branch. Weird? Let's see why I'm stating this. Assume you have no tag; Without the tag, you are using the latest commit someone did to an open source project, the camera plugin. How risky does that sound? A lot. There are tests and so on, but still, it's risky! Considering this, imagine the following scenario: you started a project for a mobile app in February and included a plugin with no tag. 2 months later you go to Quality Assurance processes and, after 1 month of proper validation, you're ready for the go live! Well, someone commits in that repository and... bum! Everything is broken or it's not working as it did before. Or now it's compiled with 64 bits library and you are also using another plugin that conflicts with that. Or...
You get the point. You didn't do anything and, all of the sudden, your project is no longer ready to go live. It's a free run and you have no control. You are totally dependent on "strangers". And this gets darker: someone might not commit on the main repository of the plugin, but the plugin is referencing the head of some depending libraries and someone commits in that dependency repository. Now it's even harder to understand why things suddenly stopped working because it's not obvious, there are no commits on the main plugin branch!

So, rules of thumb:
   1. If the plugin is critical for your business => create a fork to your own repository and merge as needed (OutSystems does it for the supported plugins)
   2. Make sure the plugin's dependencies use tags.
   3. Always, always, always use tag. Control your release.

Happy plugins!