As part of modern day mobile programming, one aspect that is often overlooked is the ability to do a force update within your app to a new version. This also applies for a soft prompt update as well. Let's spend a few mins discussing why these paths are critical for success in your app.
A force update routine in your code allows you to set a minimum version number that is supported within your app. Let's assume you track version numbers a 1.32, 1.33, 1.34, etc. Let's assume that you have a breaking change within your code. Maybe you are switching notification vendors, need to change how some stats analysis are done, etc. These changes go out in version 1.35 and after a few weeks you would like everyone to be on the new version. The problem is that a lot of users won't upgrade. generally speaking about 80% of your user populating will upgrade within say about a week. The other 20% of users are happy to just stay on an older version. As time goes on more and more of them will upgrade, but there will always be a certain percent that stay on the older version. After having your app out for more than a year, this can cause a lot of trouble as you end up having to support many different versions out in the wild.
By adding a force update prompt, you can set the minimum required version to 1.35 within your app. Your code then checks the minimum version against the installed version and prompts the user to visit the app store to download the newest version.
When you prompt the user to update, you really have two main options. You can either force the user to upgrade by not allowing them to do anything else in the app until the version has been updated. The other option is to inform them as a soft prompt, allowing the users to dismiss the message and continue in the app.
When you do a force upgrade, you will loose a certain percentage of your users each time you do it. For this reason it should not be done lightly. Do it when needed, say to update in game economy values or to rollout breaking changes, etc. However if you do it needlessly every release, you may find that you are loosing users who would otherwise stay in your app. We can't provide exact values of how many users you will loose at it will vary greatly per app and how far the force update will be (far meaning between versions). Measure your returning engagement when you rollout a force update to evaluate whether the cost of lost users is worth the forced update or not. Keep in mind that in some cases, you may orphan users who are on devices that no longer can support your newer versions of your app.
When you do a soft prompt, a good portion of your users will follow the prompt and upgrade. However there will still be a portion of users who do not. Maybe they are uninterested, don't have time or can't upgrade for compatibility reasons. Allow them to dismiss your soft prompt dialog and then you can consider re-prompting the message at a later time. For example - maybe you re-prompt the message every 7 days or something similar. Play around with values and determine what works best for you.
When you implement your solution, the one requirement that many apps might have trouble supporting is the need to access a live piece of data. This doesn't have to be anything complicated. it could just be a text file stored on a CDN with a version string in it. It could also inside of a response to an API call to your own server farm, etc. Exactly how it is delivered is not that important, the important part is that your app will in some ways need to check for the live setting every so often. If your app does not use internet, then you may have difficulties implementing such a solution.
As we go through this there will be a few things referenced:
Let's first determine our "update_threshold". How quickly do you want your clients to respond to a change in the "MIN CLIENT VERSION". Let's assume a general timeframe of 24 hours. In reality it can be either longer or slower. If you were to use a longer timeframe, such as 7 days, then that means that it could take up to 7 days for your daily player base to recognize and respond to a change in "MIN CLIENT VERSION". If you do a shorter version, such as 15 mins, that means that your clients will be checking for updates to the "MIN CLIENT VERSION" every 15 mins. This will cause stress on your "GAME SERVER" and use overhead on your client.
When your client loads, at some point towards the end of the loading process or after loading has finished you will want to start your update check routine. For the vast majority of your client loads, there will be no action needed, so this is why we want to check at the end of the loading sequence or after the loading sequence has finished. That way we do not slow down your existing loading sequence.
The routine should be as lightweight as possible. First is to validate when you last checked for an update. Read the value of the stored "min_client_check_timestamp". If the variable is missing, empty or unset then you need to check for an update. This can occur when caches are deleted, the app is reset, etc. If the stored "min_client_check_timestamp" does exist and is of valid form, then your next step is to compare it against the "update_threshold" value to see if we are out of date and need to recheck the "MIN CLIENT VERSION". So one of the following scenarios will occur:
At this point, if you exit the routine, nothing more is needed. Measure the performance of the routine and make sure that you are not causing performance issues. It is also a good idea to record in some way that you performed the update routine so that you can validate that you are not performing the routine too often.
If you need to check for an update, then you will do that now. You will want to call your "GAME SERVER" in whatever fashion is required for your situation. If you are using a CDN, then save the location of the CDN file in your "min_version_url" setting to represent the location of the cached file on the CDN. If using an API response, then your "min_version_url" setting could represent the API endpoint you need to call to get the "MIN CLIENT VERSION". The design of this step is completely up to you, so do whatever makes the most sense in your app to save and retrieve the "MIN CLIENT VERSION".
Once your client has retrieved the "MIN CLIENT VERSION" from your "GAME SERVER" then it is time to evaluate whether your clients need an update. First save the current timestamp in your local "min_client_check_timestamp" variable. Next compare the "MIN CLIENT VERSION" against the installed version of the app. If the installed version is equal to or higher than the "MIN CLIENT VERSION" then you do not need to update the app. If the installed version is older than the "MIN CLIENT VERSION" then you will want to show a message to the user to update the app (either a soft prompt or force update).
At this point, your routine is done and you can continue through your app.
An easy way to accomplish the storing of the "MIN CLIENT VERSION" is by using a CDN and storing the version number in a simple text file. However, most CDN's by default have a very long caching timeframe. The process of invalidating the cache can be tedious. For this reason, you may need to set a unique TTL (or Time-To-Live) value on your update file. You will want to adjust both your CDN TTL in cooperation with your "update_threshold" stored on your client. If you set each value to 24 hours, this means that it could take up to a total of 48 hours for all of your clients to get updated.
This is because when the clients start their update routine, the cached version on the CDN might still be a cached version and does reflect any updates within the last 24 hours. The flow would look something like this.
This is just a simple example of how we are actually introducing 2 different 24 hour thresholds when we use a CDN. This can cause up to a 48 hour delay for items to be updated.
To get around this we simply need to bring down the TTL on the CDN or the "update_threshold" on the client. In this case it might be smarter to keep the "update_threshold" as long as possible on the client, for example 20 hours and then have a shorter TTL on the CDN of say 4 hours.