About the author
Chris Griffith has been a game developer for over 19 years and a mobile developer since 2010. He’s produced dozens of apps and games for brands like Match.com, LEGO, Microsoft, Kraft, Anheuser-Busch and PepsiCo.
Chris has been a member of the PullRequest network since April 2018.
Be sure to check out other great work from Chris:
- The Most Common Issues I’ve Caught Reviewing Swift
- The Most Common Issues I’ve Caught Reviewing iOS Apps
- Top 3 Security Vulnerabilities I Find in iOS and Android Projects
This is the first part of an exploration of how to version mobile apps. While many of the principles could be applied to versioning software of all kinds, this piece focuses specifically on mobile apps.
The Significance (or Lack Thereof) of Version Numbers
What is the version number of an app supposed to convey? Of course, it is a unique identifier for any given build. It’s also a record of history and implies the difference between two or more builds. If you saw two copies of an app, v1.4.0 and v2.2.0, you’ll automatically assume:
- Version 2.2.0 is newer.
- Version 2.2.0 likely has more (or a more evolved set of) features.
- Given the full digit increase of the first number, the size of the difference is probably significant.
With the advent and mass adoption of automatic downloads from both Apple and Google’s marketplaces, most users are unlike to pay much attention to the version number of an app. Once a person downloads and installs an app, unless they run into an issue involving technical support (more on that later), they’re unlikely to even know what version of an app they are running. Because of this, I’ve noticed a somewhat cavalier approach many take for versioning mobile app releases. I believe this is a mistake and does a disservice to both users and future developers who work on the app.
There are many approaches to versioning in the stores today and varying opinions on what constitutes “the proper way.” The Facebook iOS app, as of this writing, is at v270.1 while its sister Android app is at v222.214.171.124.127. Google Chrome, on the other hand, is at v81.0.4044.124. Neither of these numbers make a great deal of sense from an outsider perspective and neither one scales very well. At the rate Facebook releases updates, every year will see the build number increment by ~50. Every release is treated with equal weight, regardless of the changes in it. The Chrome version is practically inscrutable. It’s too long and has a 4-figure number in the 3rd block. Trying to convey this version to someone could double as a working memory test.
So, how should you version your apps?
Use What’s Working For You
Before I go any further, if you or your company have a versioning system that works for you, makes sense for your business, or has simply been in place too long to change without wreaking havoc, the following suggestions may not apply to you. And importantly, there’s no need to defend a versioning system that works for its developers and users.
For those who don’t have an established system or make version choices arbitrarily, please consider the following.
A Proposal for Standardization
After a decade of mobile app development, I have found a technique that works consistently for me and every organization
I’ve worked with. In this system, a version number consists of 3 components, separated by dots. I will refer to them as
Major, Minor, and Revision numbers (ie -
Major: 1 Minor: 7 Revision: 2
Any of these numbers can climb as high as they need and don’t need to be limited to 1 figure (ie -
2.17.3 is valid).
When any number increments, all the components to the right reset to 0. If you’re a Mac user, you may notice some
similarities between this a what Apple has used for its operating systems since the introduction of OS X. However,
unlike OS X, the system I’m proposing actually encourages the major number to change over time. Let’s dig into the
implied meaning behind each of these components.
This is the big one, the slowest to change, and the only one that never resets. The first number indicates, as suggested by the name, a significant revision to the app. This might entail a refreshed UI or an entirely new section of the app represented by a new tab in the interface. For document-based apps, this is a good place to denote backwards-compatibility with previous major versions, or introduce a new format. Because these types of significant changes tend to happen infrequently, major numbers (should) persist a relatively long time. Changing the major version number conveys to the user that much has changed, and as the number persists, it conveys in subsequent versions that not much has changed.
Examples of a major version could include things like an overhaul to navigation or design, the addition of a major feature such as user-to-user chat, or updates to how the app uses device hardware, such as a camera, to perform core core functionality.
Many app publishers use major version releases as an opportunity to update branding such as the app’s icon and screenshots. This helps make it clearer to end users that there’s been a sizable change.
This tends to be the number that changes the most for mobile apps. A minor version bump should signify new features or a refinement of existing feature while the app experience by and large remains the same. For document-based apps, backwards compatibility is assumed between versions (unless Minor is reset to 0).
Examples of a minor version could include things like UI look and feel enhancements, changes to optimize performance and battery consumption, or adding a leaderboard for a game.
Known as PATCH in Semantic Versioning 2.0.0. Historically, you’d notice more Revision versions for Android apps than iOS apps since at a time new App Store app versions could take up to 2 weeks to be reviewed and approved whereas developers could upload new app versions to Google Play daily. At the time of this writing, App Store review times have drastically decreased but the pattern of releasing iOS versions less frequently lives on to some degree.
This number is used to denote very small changes, ideally invisible to the user, such as updating a 3rd party service SDK or fixing a crash. If only this number changes between releases, a user can expect that there are no new features and that updating simply improves the overall experience in some slight (possibly intangible) way. Whenever the minor version rolls to a new value, this resets to 0.
Benefits of This Convention
- Simplicity - it’s easy to understand. There is always a maximum of 3 numbers and the increment accordingly to the overall amount of change in the app.
- Scalability - it grows over time without becoming unwieldy. Over the lifetime of an app in the store, it will take a long time for the Major number to become so large as to be awkward - no Facebook v538.0 here. And each time a number increments, all numbers to the right reset, keeping the values manageable.
- Flexibility - it factors in rapid development cycles and the need for hot fixes. Depending on the app and size of the features being rolled out, preference can be given to incrementing Minor or Revision more. Defining specific rules about when each number increments can be done on an app by app basis if necessary without breaking the system.
- Mutually Beneficial - it bears significance to both the developer and the end user. A user can read the version history in the store and draw a connection between features and numbers. From the developer’s end, when attempting to troubleshoot a problem there’s a clear understanding of what feature set is active on a person’s device.
What About Version Codes and Build Numbers?
So far, this system has only addressed the version number shown to users in the app marketplaces - the public version number, if you will. Both iOS and Android have other values, referred to as the build number and version code, respectively. On Android, the version code is a unique integer that is always incrementing from one store version to the next. Just think of it as a counter. To submit an app to Google Play, a version must have a higher number than the previous one. That’s it.
On the Apple side, for the same version number we talked about previously, the build number must increment (but can be reset with a new version number). This is best explained via an example. Say you have v4.10.1 (Build 54). To upload a new version of 4.10.1, it must have a higher build number than 54. But if you upload v4.10.2, you can reset the build to 1. Some developers do this and some (including myself) find it confusing. In essence it’s adding second Revision number which could further complicate understanding. Because of this, and for consistency’s sake, I prefer to treat both numbers the same and follow Google’s more restrictive rules. The build number always increases.
Where to Display the Version
As mentioned earlier, there when a user of your app (or someone in the QA department) may need to be able to easily access the version number. The platforms are not consistent about making this information readily available for an app already installed on a device. On some versions of Android, you can dig into the advanced settings for a particular app and discover the version number there, though this is not necessarily user-friendly. On iOS, there is no built-in mechanism. If the app has a Settings bundle it’s fairly common practice to print the version there. If practical and possible (I understand it may not be), I highly recommend placing the version number in whatever the equivalent of an About/Settings screen in your app is. In Part 2, I’ll elaborate on the technical aspects of placing this version in multiple places to make it convenient to discover it at any time.
It is my hope that this has sparked some ideas about how to integrate such a versioning system into your existing app(s) or those you plan to build. In Part 2, I will go into detail as to how I automate this process to make it simpler and give it actual meaning from a developer standpoint rather than just a random number ever increasing. There will even be some code snippets you can copy/paste into your projects to make the job easier :)
Be sure to check out other great work from Chris: