10 product development practices that will give you full flexibility and control on your mobile app
Product managers, startup founders and even software developers want to have maximum control on the products they build. Agile companies need to constantly change things and measure their impact, it's a pre-requisite to almost everything they build.
The problem with mobile apps
Native mobile apps are quite different than web apps: while web apps are refreshing themselves automatically whenever there’s a new version of the product, mobile apps are installed locally on each device. Upgrades require new versions to be submitted to the different app stores for review. This process can take a few days and even when the app is approved - the upgrades are not performed immediately (and in some devices they never happen because the auto-upgrade is disabled).This is a cumbersome process and it makes it hard for companies to move fast and break things freely.
As a B2C startup, aiming to move fast and make frequent changes, we suffer from this problem a lot. Releasing a new version every few weeks is part of our frequent shipping culture, but it’s not always enough. Changes and fine-tunes to the business logic are required on a weekly basis and the fact that some users just don’t upgrade their apps makes it even more complex.
10 product design principles to tackle this problem:
Here are 10 design principles that helped us get maximum control over our apps after they are released and installed. Using those techniques help to maintain a flexible product that can change dynamically without having to create a new product release for every change.1. Load the app strings from the server
Loading the app strings form the server means you can modify the strings after the app is already released. As a PM this is a priceless capability as UX Writing is a very hard process that never really ends.
This capability becomes very handy in various scenarios:
- Whenever you find a typo in production and want to fix it ASAP
- Whenever there’s a need to change some explanations due to changes in the business logic
- Whenever a certain UI component is not clear enough and there’s a need to improve the microcopy
If you are worried about performance implications, it’s recommended to develop a “smart” download mechanism that will only fetch the strings when something has changed.
2. Load the photos and icons from the server too
Having this capability ensures that the look and feel of the app can be changed (to some extent) without releasing a new version to the stores.
Have your resources stored remotely and gain maximum control without involving any development at all.
3. Store dictionary objects in the database
This one is a bit more technical: when writing code, enums are often used to represent a set of restricted options (colors, cities, gender, cancellation reasons).
Instead of holding simple enums in your client code - store dictionary objects in the database. The app should load those dictionary objects upon launch, and use them like enums.
The big difference here is that changes to the enums can be done remotely (and on-the-fly) in one centralized location that immediately impacts the whole system without involving additional development on the apps.
Instead of holding simple enums in your client code - store dictionary objects in the database. The app should load those dictionary objects upon launch, and use them like enums.
The big difference here is that changes to the enums can be done remotely (and on-the-fly) in one centralized location that immediately impacts the whole system without involving additional development on the apps.
4. On/off switches:
On/off switches allow turning off features remotely and instantly.
You develop something, you give it a try, and if it doesn’t work as planned - you rollback immediately without asking for permission.
On/off switches become very handy in the following scenarios:
- A new feature is relying on some business assumptions that don't come true
- A new feature is released with a bug (have mercy!) or with a limitation and makes more harm than good
- A new feature is set to work in a period of time (i.e. holidays) and after a while, it should be turned off.
In a dynamic environment where uncertainties are a part of the game - developing important features with on/off switches will provide some level of assurance to the product.
5. Move logic to the server
This one is a killer and my favorite item in this list.
Let’s say you develop a delivery app where customers place their orders, receive the delivery and pay through the app.
Now, let’s say you need to develop a cancellation policy for customers who are canceling their orders in the last minute. Developing a simple solution such as a fixed cancellation fee is not hard, but the troubles begin when new policies are added. What may begin as a simple, fixed cancellation fee, may certainly evolve into different levels of fees, percentages based on the order size, first-time warnings etc.
While all of those scenarios can be developed in the client side - there is a much better solution: move the business logic to the server side and have the apps present the results in a generic way.
This architecture allows frequent logic changes to be made in one centralized location (in the server side) and each change impacts all the customers, including the ones who haven’t upgraded their app for a while - instantly. No need to release new apps, no need to deal with old functionality vs. new, etc.
Changes are made only once, there’s no need to submit new app releases to the app stores, and the new logic is enforced to all the users, including the ones with older versions of the app.
6. Server-side UI rendering
This one is not a common pattern in mobile apps, but in extreme cases, it can be a good solution to some business needs:
Instead of coding the UI logic in the app itself, let the server do the hard work: analyze what’s required (based on the user, the process, the stage in the process) and create the UI logic behind the scenes.
The results are sent back to the clients (as instruction capsules defining what to show in the UI) and the app uses those instructions to draw the UI in a pretty “dumb” way.
Instead of coding the UI logic in the app itself, let the server do the hard work: analyze what’s required (based on the user, the process, the stage in the process) and create the UI logic behind the scenes.
The results are sent back to the clients (as instruction capsules defining what to show in the UI) and the app uses those instructions to draw the UI in a pretty “dumb” way.
Yes, it feels like moving back from the modern "fat-client” approach to a shallow thin client that acts almost as a website, but it sometimes makes sense in mobile, because unlike web applications, native apps cannot be refreshed without involving app upgrades through the stores.
Server-side rendering bypasses this problem and gives your product an extra layer of flexibility.
7. Create generic components to be used on various occasions
Instead of creating a special Christmas version of the app and submit it to the stores in the last minute (together with 2 million other apps that are doing exactly the same thing) - how about having a few generic UI components that can act as promotional popups and themed decorations?
Such components can have:
- Specific conditions when to be shown (dates, user segmentation, geographic audiences)
- UI definitions (size, layout, colors, title and body, images if relevant, actions and more)
- Behavioral specifications (stage in the workflow, how many times to be shown, etc.)
We’ve created a bunch of generic components and have been using them widely ever since.
8. Add backward compatibility to your server API
This one is a must:
As you release new versions of your mobile app, there’s always going to be a group of users that do not upgrade.
Those are usually the “less technical” users or the ones that ran out of space and turned off the auto-update option.
Those users are harming your business: not only they do not enjoy the latest of greatest of your product, but they also require that your server will support multiple versions (and multiple logics) simultaneously.
In cases where you need to enhance some API functions but still want to support older versions of the app - add the following meta-data to all of your API methods:
- OS type (iOS, Android, Windows, etc.)
- User ID
- App version
The above 3 will allow you to implement different variants of your services logic based on different versions of the app, different OS (i.e. Android vs. iOS) and even based on user segments.
9. Invest in A/B testing
You can try to avoid A/B testing and conduct periodic product experiments instead (using flags and on/off switches), but eventually, the time will come and you will have to add this important capability in order to isolate your experiments from market “noise”.
How else would you be able to tell what caused those metrics to change?
- Was it the new welcome tour that improved the conversion rate? Or maybe that new marketing campaign is bringing better cohorts?
- Was that the new feature that increased the GMV? Or maybe it’s because of the holidays?
- Was it a bug fix that boosted registrations rate or maybe it’s the summer that has finally arrived?
Market trends are probably stronger than any feature you create, especially if your product has a seasonality effect. To be able to nail down the impact of each change - the product must have A/B test capabilities.
Market trends are probably stronger than any feature you create, especially if your product has a seasonality effect. To be able to nail down the impact of each change - the product must have A/B test capabilities.
10. Force upgrade
In the rare cases where the product is going through a major change, it may become too costly to keep old versions alive with backward compatibility.
In such cases, you may need to use the deadliest weapon in the world, also known as: The Force. Upgrade.
A force upgrade is a blocker that blocks the users from using the app until they upgrade to the latest version.
It pops up as an alert and forces the users to upgrade by taking them straight to the app store.
This is, of course, not a great user experience (to say the least), and may cause some users to get lazy or upset, and simply uninstall the app, so this option should be the last resort and only be used when there’s absolutely no other way.
A slightly lighter version of this technique is to block specific functions instead of the whole app.
The user can still use the old version of the app, but once he tries to activate a feature that is no longer supported - he gets a generic error message saying the app should be upgraded.
So there you have it, 10 techniques to design a mobile app that is highly flexible and can change based on the changes in the business needs.
Liked this article? There's more:
This post has been published on www.productschool.com communities.
Follow me on twitter @gilbouhnick or subscribe to the Mobile Spoon newsletter and get my occasional blogs directly to your inbox.
Liked this article? There's more:
- Your product's early adopters - the good, the bad and the ugly
- Here's to trade-offs and compromises. Your product's best friends
- What to do when you can't believe your customers, friends, and even your mom...
This post has been published on www.productschool.com communities.
Follow me on twitter @gilbouhnick or subscribe to the Mobile Spoon newsletter and get my occasional blogs directly to your inbox.
Comments
Sticking with web...
Post a Comment