Перейти к содержанию
Innovialabs

Как заставить пользователей обновить приложение

Практика3 мин

Коротко

Приложение при запуске узнает с сервера минимальную и актуальную версии: ниже минимальной — блокирующий экран обновления, ниже актуальной — мягкое предложение, а API продолжает поддерживать старых клиентов до перехода.

Короткий ответ

Нужны две вещи, заложенные с первого релиза:

  1. Проверка версии при запуске. Приложение получает с бэкенда или из remote config два значения: min_supported_version и latest_version.
  2. Две реакции. Версия ниже минимальной — жесткое обновление (hard update), без него дальше не пройти. Ниже актуальной — мягкое (soft update), можно отложить.

Если такой проверки нет в уже установленных версиях, «заставить» их обновиться нельзя — только сломать их API, что хуже. Поэтому механизм добавляют в самую первую версию.

Проверка минимальной версии

Источник значений:

  • Свой бэкенд — эндпоинт конфигурации или заголовок в ответах API. Полный контроль, можно задавать разные версии для iOS и Android.
  • Remote config (например, Firebase Remote Config) — меняется без деплоя, есть условия по платформе и аудитории.

Пример конфигурации:

{
  "ios":     { "min_supported_version": "2.3.0", "latest_version": "2.5.1" },
  "android": { "min_supported_version": "2.3.0", "latest_version": "2.5.1" }
}

Важно:

  • Сравнивайте версии по частям как числа, а не как строки: 2.10.0 новее 2.9.0.
  • Повышайте минимальную версию только после того, как сборка доступна в обоих магазинах — иначе пользователь увидит «обновитесь», а обновления еще нет.
  • Если конфиг не загрузился (нет сети), не блокируйте пользователя — используйте последнее сохраненное значение.
  • Дополнительно передавайте версию приложения в заголовке каждого запроса. Сервер может ответить кодом 426 Upgrade Required, если клиент слишком старый.

Android: Google Play In-App Updates

Google Play предоставляет API In-App Updates с двумя режимами:

  • IMMEDIATE — полноэкранный поток обновления, Play сам скачивает, устанавливает и перезапускает приложение.
  • FLEXIBLE — загрузка в фоне, пользователь продолжает работать; когда загрузка завершена, вы предлагаете перезапуск.
val appUpdateManager = AppUpdateManagerFactory.create(context)
appUpdateManager.appUpdateInfo.addOnSuccessListener { info ->
    if (info.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE &&
        info.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)
    ) {
        appUpdateManager.startUpdateFlowForResult(
            info,
            updateLauncher,
            AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE).build()
        )
    }
}

Приоритет обновления можно задать при публикации через Play Developer API, а clientVersionStalenessDays() показывает, как давно доступна новая версия. API работает только для установок из Google Play, поэтому собственная проверка min_supported_version все равно нужна.

iOS: своя логика

Встроенного аналога In-App Updates в iOS нет. Обычный подход:

  • Сравнить текущую версию с min_supported_version и latest_version из вашего конфига.
  • Показать свой экран или диалог и открыть страницу приложения в App Store.
  • Можно запросить текущую версию в App Store через iTunes Search API, но собственный конфиг надежнее: вы сами решаете, когда версия становится обязательной.

Учитывайте phased release в App Store: новая версия доходит до пользователей постепенно, при этом вручную обновиться можно сразу.

Версионирование API для старых клиентов

Принудительное обновление — крайняя мера. Основная защита — API, совместимый со старыми версиями:

  • Добавляйте поля, но не удаляйте и не меняйте смысл существующих.
  • Ломающие изменения выпускайте в новой версии API (/v2/...) и держите старую, пока доля клиентов на ней не станет приемлемой.
  • Отслеживайте распределение пользователей по версиям приложения — это основа решения, когда поднимать минимальную версию.
  • Клиент должен корректно переживать неизвестные поля и значения перечислений.

UX мягкого и жесткого обновления

МягкоеЖесткое
КогдаНовые функции, исправленияУязвимость, несовместимый API, юридические требования
ВидБаннер или закрываемый диалогПолноэкранный экран без обхода
ЧастотаНе чаще, чем разумно, с запоминанием «позже»При каждом запуске до обновления
ТекстЧто нового и зачем обновитьсяПочему без обновления нельзя продолжить

Не злоупотребляйте жестким обновлением: каждый блокирующий экран — риск, что часть пользователей не вернется.

Частые вопросы

Напрямую нет. Остается только поддерживать старый API или вернуть ошибку, которую старая версия покажет как есть. Поэтому механизм проверки нужно добавить как можно раньше.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.