Пока приложение не вышло, ошибка стоит недорого: поправили и собрали заново. После публикации всё меняется — у людей на телефонах уже стоит ваша версия, и снять её нельзя. Разберём, как выпускать обновления, чтобы неудачный релиз не превратился в потерю клиентов.
Раскатывайте по частям
Google Play умеет отдавать новую версию не всем сразу, а доле пользователей: сначала пяти процентам, через сутки двадцати, потом всем. Если в версии окажется ошибка, её увидят десятки человек, а не вся база, и раскатку можно остановить одним нажатием.
В App Store есть похожий механизм поэтапного выпуска на семь дней. Он выключен по умолчанию — включать нужно руками при подаче версии.
Правило простое: чем крупнее изменение, тем медленнее раскатка. Правка текста — можно сразу всем. Переписанная авторизация или новый способ оплаты — только поэтапно, с наблюдением за ошибками.
Старые версии остаются работать
Даже после выпуска обновления часть людей неделями сидит на прежней версии: автообновление выключено, память кончилась, телефон старый. Поэтому сервер обязан продолжать понимать старые приложения.
Практическое следствие: контракт обмена данными можно только расширять. Добавить новое поле в ответ — безопасно. Переименовать существующее, изменить его тип или убрать — значит сломать приложение у всех, кто не обновился. Мы однажды переписали ответ сервера под новую версию и обнаружили, что установленное у клиента приложение перестало открывать половину экранов.
Если менять контракт всё-таки нужно, делают вторую версию адреса и какое-то время держат обе: старые приложения ходят по-старому, новые по-новому.
Когда обновление не нужно вовсе
Часть изменений не требует новой версии в магазине: тексты, цены, баннеры, состав меню, правила расчёта — всё это может приходить с сервера. Чем больше вынесено на сервер, тем реже приходится проходить проверку магазина и ждать сутки ради правки одной строки.
Для приложений на Flutter есть ещё один путь — доставка исправлений мимо магазинов. Мелкая ошибка чинится за минуты, без проверки Apple и Google. Работает не для всего: изменения в нативной части и новые разрешения так не доставишь, но для правки логики этого достаточно.
Сломанный релиз: что делать
Первое — остановить раскатку, если она поэтапная. Второе — вернуть предыдущую версию: в Google Play можно снова выпустить старый номер сборки, в App Store — вернуть прошлую версию из списка. Третье — выпустить исправление и провести его через ускоренную проверку, если поломка критичная: у Apple для этого есть запрос на срочное рассмотрение, и по реальным поломкам его обычно одобряют.
И четвёртое, о чём забывают: сообщить людям. Короткое уведомление «знаем о проблеме с оплатой, чиним» снимает половину гневных отзывов, а отзывы влияют на выдачу в магазине надолго.
Что писать в «Что нового»
Этот текст читают, и он влияет на решение обновиться. «Исправлены ошибки и улучшена стабильность» не говорит ничего. «Поиск по заказам стал работать по номеру телефона, исправлена оплата Kaspi на Android 14» — говорит. У Google Play здесь ограничение в 500 знаков, у Apple 4000, но длинный текст никто не читает: три-пять строк по делу.
Порядок, который работает
Собрали версию, прогнали на живых устройствах, а не только в эмуляторе. Выпустили на малую долю. Сутки смотрели на ошибки и отзывы. Расширили до всех. Всё это занимает на день дольше, чем «выпустить и забыть», и экономит куда больше времени, когда что-то идёт не так.
Принудительное обновление: когда оно оправдано
Иногда старую версию оставлять нельзя: изменился протокол оплаты, найдена дыра в безопасности, сервер больше не умеет отвечать по-старому. На этот случай в приложении делают проверку минимально допустимой версии: при запуске приложение спрашивает сервер, годится ли оно, и при отрицательном ответе показывает экран с предложением обновиться.
Важно, чтобы этот экран был вежливым и объяснял причину, а кнопка вела прямо в магазин. И ещё важнее — чтобы порог версии задавался на сервере, а не был зашит в код: иначе поднять его вы сможете только новой версией, что лишает механизм смысла.
Злоупотреблять принудительным обновлением не стоит. Каждый такой экран — часть людей, которые в этот момент отвалятся: у кого-то нет места на телефоне, кто-то в роуминге, кому-то просто некогда. Требуйте обновления только тогда, когда старая версия действительно неработоспособна.
Что смотреть после выпуска
Первые сутки после раскатки полезно держать перед глазами четыре цифры. Доля сессий с падениями — если она подскочила против прошлой версии, останавливаем раскатку. Число установок и удалений — резкий рост удалений говорит о проблеме, которую не видно в отчётах о падениях. Оценка и свежие отзывы — люди пишут о поломках раньше, чем те попадают в статистику. И ключевые действия в приложении: заказы, оплаты, регистрации — если они просели, значит что-то сломалось в сценарии, даже если приложение не падает.
Последний пункт самый коварный. Приложение не вылетает, отчётов нет, а оплаты упали вдвое, потому что кнопка уехала за границу экрана на популярной модели телефона. Такое находится только по цифрам сценария и по отзывам.
Хранение данных между версиями
Обновление не должно стирать то, что человек накопил в приложении: корзину, черновики, настройки, вход в аккаунт. Чаще всего это ломается при изменении структуры локальной базы: новая версия ожидает новую схему, старые данные под неё не подходят, и приложение либо падает, либо тихо очищает всё.
Правильный путь — миграции: код, который переводит данные из старой структуры в новую при первом запуске новой версии. Их нужно писать сразу, а проверять — обновлением поверх предыдущей версии, а не установкой с нуля. Разработчики почти всегда ставят приложение начисто и потому не замечают проблему, которую увидят все пользователи.