You can’t make people update

The fix is live, and people are still on the broken version. Build the thing that asks them to update, before you need it.

You ship on a Friday. By Saturday morning, the crash reports are coming in.

The fix is easy. You find it, build it and send it to Apple. Then you wait for App Review. And even when the fix is live, not everyone on the broken version updates. Some phones weren’t on charge last night. Some are on an old phone that can’t run the new version.

They still have your broken app, and you have no way to reach them.

Nobody plans for this

Most clients don’t think about maintaining their app. It’s easy to say, “Just build the app, we’ll add that later.” But later never comes. And when it does, you can’t guarantee people will behave how you expect.

Updates are much better than they were. Apple hid them, and most phones now update overnight. But only if the phone is on charge, isn’t in Low Power Mode and has a good connection. Apple optimises for battery, not for your app update, so don’t take it for granted. The one thing you still can’t control is getting people off an old version.

It would be lovely if everyone could stay on their version forever. Then real life happens. A version has a bug that crashes or loses data. An old version calls an API that you’ve changed or switched off. Or you want to stop paying for an external service that only the old version still uses.

Each time, you need a way to get people to update. Or, as a last resort, to stop them using the app.

In the most polite way.

One small file

You can do this with a version API, or a settings API. It sounds bigger than it is.

Every time the app opens, it fetches one small file. The file holds a version number and a switch:

{
  "version": "2.4.0",
  "force_update": false
}

If the app is older than that version, it shows a polite prompt with a link to the App Store. People can tap “Not now” and carry on.

If you set force_update to true, the prompt becomes a screen they can’t get past. That’s the one you use when the old version is broken.

That’s it. When a bad version gets out, you change one line, and every copy of your app hears about it the next time it opens.

Ask nicely

A screen that blocks someone is a harsh thing to show them. They opened your app to do one thing. So be careful with it.

Only force an update when the old version is broken, or can’t work any more. Crashes, lost data, a security hole, an API you’ve switched off. Never for a new feature.

Say why. “This version can lose your notes. The update fixes it.” is better than “Update required.”

Let people finish. If they’re halfway through something, let them save it first.

And have the fix in the App Store before you flip the switch. Sending people to update to the same broken version helps nobody.

If you can’t wait, Apple offers an expedited review. Use it sparingly. Your app isn’t that important to Apple. It’s for emergencies, to save your reputation or your business, not something you ask for every month.

Tell App Review

Apple has rejected apps that fetch a config file. Some apps used one to switch features on after review, so to Apple it can look like hidden functionality.

So say what the file does in your review notes, and that it only ever asks people to update. Even better, attach a short video of the prompt and the blocking screen in App Store Connect. Then the reviewer knows exactly what happens.

Build it before you need it

Here’s the catch. This only works for versions that have the check. You can’t add it to a version that’s already on people’s phones. So it has to go in the first version you ship, the one you’re sure won’t need it.

And it takes almost no effort. The file can be a static file anywhere.

That’s the real cost of “we’ll add that later”. The day you need it is too late to add it.

For the developer

Host the file away from your main API, for example on a CDN. If your API goes down, the file still answers. Give it a short cache time, so a change reaches people quickly.

If the call fails or times out, open the app as normal. A safety net that can stop your app opening is just a new way to break it.

Compare versions part by part, as numbers. As text, 2.10.0 comes before 2.9.0.

If the fix needs a newer iOS, people on older phones can’t install it, so a forced update locks them out. That’s something you have to live with. People who don’t update their phone are rarely the ones using or paying for apps, so it may not be a big deal. But be aware of it, and keep an eye on which iOS versions your users are on.

Check again when the app comes back to the foreground, not only on launch. People leave apps open for weeks.

Before you need it, test both states. Point a test build at a file with a higher version, and check the prompt and the blocking screen.

Later never comes. Build it now.

The states nobody designs