Creating mobile apps with OutSystems is easy. That's a lofty claim right there, but I'm sticking to it; anyone who's developing mobile apps with OutSystems can substantiate that claim. But just because it's easy, it doesn't mean there's not stuff you need to think about, especially if you're developing something with a bigger target audience in mind.

There are a few things you need to keep in mind at all times if you're thinking about a scenario at scale. Here are six considerations for you and anyone else who has that amazing mobile app in mind. (Each consideration has a tip at the end, for those who want to get right to the heart of the matter.)

By the way, tip #6 is the most important one. Just saying. (But don't skip!)

1. Don’t Run Away From the Stores

Before we get into why you shouldn’t run away from the stores, let’s look at what happened back in the days of web apps. Whenever you wanted your audience to get the latest and greatest, all you had to do was click that nifty "one-click publish" button, and that was it. "Hit F5, and you're done.” Here's that happy path, simplified:

Updates get to customers fast

OK, true: we're not listing everything that happens under the hood; the magic that makes it all happen, all the way from development down to production. In this scenario, you could still bump into certain issues: adding proxies, considering network conditions, minding cache servers and load balancers. Add a front-end farm to support all this, and the scenario gets trickier and trickier:

Maybe not that fast…

And this is all without minding the client's firewall, the browser cache, etc. Nevertheless, you have almost a full grasp and control over the condition in which your app is served. Almost.

So, you might be wondering why mobile would be any different. You already know that OutSystems 10 has amazing capabilities that facilitate the deployment process: you don't need to go through the whole store submission process to push updates to your customers. There are lots of apps in the wild that already do this, very conveniently, for devs and users alike—for instance, Facebook with the “lite” version of their mobile app.

Facebook Lite updates

This feature, which is called hydration, pushes updates to users on the fly, avoiding extremely complex round trips to app stores. This is what a typical update scenario looks like:

OutSystems 10 mobile apps automatically updated

Hmm… what does this remind you of? Could it be the one-click publish scenario we mentioned for web apps before? Alas, this feature doesn't mean that apps are submitted in stores for life. The mechanisms that check for updates get the delta from what's new in the server and the version the user currently has. As you can see, if the user is constantly picking up updates, relatively small updates will be all it takes to keep your app fresh:

Auto-updating mechanism. A customer that installs the app with V6 in production will get a delta of 1120 files.

However, picture a scenario where users install your app some two months after you released it in the app store. When they open the app, the in-app update mechanism will check for updates and compare them to the server's version. Oops! Looks like there are 1120 new changes (V6 is in production, for instance). If the files have, on average, 10KB each, this will mean the user will need to fetch 11.2MB just for that update.

This creates overhead and, in bad network conditions, or when moving through networks (getting into elevators, into the subway, you name it), this might create some unexpected hiccups that might seriously compromise usability.

Now that you know what can happen when the best-laid update plan goes awry, you’re ready for our first tip.

Tip #1: don't shy away from stores. Create checkpoints for store updates whenever you start to identify big differences between the latest version and the originally submitted one. Try to strike a balance there: if you spot a typo and need to correct it, you probably don't need to submit that update to the store.

2. Understand the Upgrade Model

On-the-fly updates are amazing. However, some features require the deployment of a new version of the shell. Namely, using new plugins that make use of the device's native capabilities: camera plugins, Bluetooth, or NFC, for instance. In these cases, you'll have to deploy your app to production and go through the store again.

Here's an example: imagine you have an app in which you included QR scanning that happens with just the press of a button. You scour the OutSystems Forge and grab the supported barcode plugin. This will require updating to a new shell, as it'll now interact with the device's native capabilities and code, making use of its camera. How do you glue everything together? Publish to the store or deploy to production first?

Adding native interactions

The first thing you have to do is protect your code, so everything doesn't blow up if the plugin is still not included. Hide the button, provide a graceful message that informs the users when they click, whatever. Just make sure you don't let the app scan if the user still doesn't have the plugin. This is a must no matter your deployment strategy. Now, for the complete experience to be in your users' hands, they will need both the new shell that incorporates the plugin and the respective logic in the app.

There are two approaches you can use to make sure you don't miss a beat.

First Approach: Patient, Long-Term Plan

If you know you need the plugin, release a new shell in the stores as soon as possible (we advocate for “immediately”). Wait a few weeks until your customers update to that new version of the app in the stores (or force an update in the app itself). After that, you can deploy your new feature to production.

Deploy to the stores in advance

Second Approach: Deploy Code First

You might not know in advance whether you'll need a given plugin or not. So, taking the long course and preparing beforehand might not be possible. Hindsight is 20/20; you know how it goes. Go to production with that part of the code well protected (quick check, if the plugin is not present, display a graceful message). Then, deploy to stores right away.

Deploy at the same time

Keep in mind that you won’t be able to control how long users will have an old version of the app unless you programmatically force them to update from the store:

Different paths — hard to control with thousands of users

Tip #2: Although you can push application updates to users, native functionality needs to be deployed through an app store update. You need a combined strategy that'll have your deployments reaching users in a "safe" way.

3. Mind the Infrastructure

If you're not using a cloud environment, the responsibility of having your infrastructure ready rests in your hands. So, beyond all the work you need to do on your app anyway, you are the one who will have to take care of dealing with cache servers, load balancers, and several front-end servers.

This might mean that when you deploy to production, some users might not get the new version at the same time. Some might even be affected by cache poisoning, for example, the cache returning incorrect JavaScript files along with new HTML files.

Possible “cache poison”

Tip #3: Properly set up the production infrastructure and be aware of how you deploy to production.

4. You Will Have a Customer With a Rooted Obscure 3422-y-k-x-a-89002893-Whatever-Model-It-Is Device

Now, this isn't specific to OutSystems. These considerations ring true for all mobile apps. Due to the market's fragmentation, particularly in Android and if you're targeting the B2C crowds, there'll always be customers with some arcane device where something will not work as expected. You don't need address all scenarios here, but make sure you protect your app by catering to the minimum common denominator.

Are you going to make your apps compatible with rooted devices where you have no idea what's hammered in or not? How will you deal with a complaint from a customer using a device you can't troubleshoot or ever will have access to?

Tip #4: Prepare yourself for the fact users these days will get whatever device seems to fit their needs. There are some obscure ones that you just won't be able to troubleshoot or cater for.

5. Phased Rollout Is King

Because you don’t have a lot of control (on the user side of things), a phased rollout is almost mandatory. Test a release with a sample of your users, using a DevOps-y approach: release to a restricted group first (your beta testers, who will relish the opportunity and feel privileged) and then roll it out to the masses.

It's the same logic that TestFlight and Play Beta use, just faster and better! Maybe you already have the new button to scan those QR codes available, but you want to make sure that it's working correctly. Make it visible only to that special restricted group of users. Then, when you're sure everything's working as intended, roll it out for the world to use.

Tip #5: Take advantage of a faster update cycle to gather feedback from a subset of your user base.

6. Just Because It’s Easy…

... doesn’t mean you should skip the documentation. Read the docs! Most developers out there are used to a web app world where the things you have to take in consideration are totally different than for mobile apps. Performance, battery consumption, network conditions, device fragmentation, and all those mobile world intricacies have to be on your mind from the get-go.

This technology makes it easy to bring your amazing ideas to life. But a great idea with poor execution is doomed to fail if you don't take proper care of it.

Tip #6: Read OutSystems Mobile Best Practices and consider this training: Becoming a Mobile Developer.