Wydajesz poprawkę krytycznego błędu, a tydzień później połowa użytkowników wciąż korzysta ze starej wersji. Zmieniasz API na backendzie, a stare wersje aplikacji zaczynają się sypać. Dostawca wyłącza usługę, z której korzysta wersja sprzed roku, a Ty nie masz jak powiedzieć tym użytkownikom, że muszą zaktualizować aplikację.
Wszystkie te sytuacje rozwiązuje jeden mechanizm: minimalna wspierana wersja, czyli możliwość wymuszenia aktualizacji. Jest prosty do zbudowania, ale ma jedną cechę, o której wiele firm dowiaduje się za późno: działa tylko w wersjach, które już go mają.
Dlaczego użytkownicy nie aktualizują aplikacji
Automatyczne aktualizacje są w obu systemach domyślnie włączone, a mimo to stare wersje żyją długo:
- telefon aktualizuje aplikacje tylko przy Wi-Fi i ładowaniu, więc część urządzeń robi to rzadko,
- część użytkowników wyłączyła automatyczne aktualizacje,
- nowa wersja wymaga nowszego systemu, niż ma telefon,
- wydanie trafia do wszystkich stopniowo: w App Store phased release trwa 7 dni (1%, 2%, 5%, 10%, 20%, 50% i 100% użytkowników z automatycznymi aktualizacjami), w Google Play tempo staged rollout ustalasz sam.
W efekcie w każdej aplikacji działa naraz kilka, a często kilkanaście wersji. Rozkład zobaczysz w Play Console, w analityce albo w Crashlytics. Zwykle to nie jest problem — dopóki nie musisz się którejś z nich pozbyć.
Kiedy wymuszać aktualizację, a kiedy nie
Wymuszona aktualizacja blokuje użytkownika, który otworzył aplikację w konkretnym celu. To narzędzie na sytuacje, w których stara wersja nie może działać dalej:
- luka w bezpieczeństwie w starej wersji, np. wyciek tokenów albo brak weryfikacji certyfikatu,
- wyłączona usługa zewnętrzna, z której korzysta stara wersja — przykłady opisujemy w tekście o wycofanych SDK i API,
- niekompatybilna zmiana w API, której nie da się rozwiązać po stronie backendu,
- błąd, który psuje dane albo naraża użytkownika na straty, np. w płatnościach,
- wymogi prawne, np. zmiana sposobu przetwarzania danych osobowych.
Nowa funkcja, odświeżony wygląd czy chęć podniesienia statystyk nie są powodem do blokowania aplikacji. Do tego służy łagodna prośba o aktualizację, którą użytkownik może odłożyć.
Dwa tryby: prośba i blokada
Prośba o aktualizację Wymuszona aktualizacja Co widzi użytkownik komunikat z przyciskiem „Aktualizuj" i „Później" ekran, którego nie da się zamknąć bez aktualizacji Kiedy stosować ważne poprawki, nowe funkcje, koniec wsparcia za kilka tygodni stara wersja nie może działać dalej Ryzyko niewielkie frustracja i gorsze oceny, jeśli nadużywaneDobrą praktyką jest łączenie obu: najpierw przez kilka tygodni prośba, a dopiero potem blokada. Użytkownik dostaje czas, a Ty widzisz w statystykach, ilu osób blokada w ogóle dotknie.
Android: In-App Updates
Google udostępnia bibliotekę Play In-App Updates z dwoma trybami:
- elastyczny — aktualizacja pobiera się w tle, a użytkownik dalej korzysta z aplikacji i na końcu zatwierdza ponowne uruchomienie,
- natychmiastowy — pełnoekranowy komunikat Google Play, aktualizacja i restart aplikacji, zanim użytkownik przejdzie dalej.
To wygodne rozwiązanie, ale ma ograniczenia. Działa tylko dla aplikacji zainstalowanych z Google Play. Priorytet wydania, na podstawie którego aplikacja wybiera tryb, ustawia się przez Play Developer API (inAppUpdatePriority, od 0 do 5), a nie w interfejsie Play Console — czyli w praktyce w procesie wydawniczym, np. w fastlane. Do tego biblioteka mówi tylko, że jest nowsza wersja i jak bardzo jest ważna, ale nie wie, czy obecna wersja może jeszcze działać. Tę decyzję lepiej trzymać po swojej stronie.
iOS: nie ma gotowego mechanizmu
Apple nie udostępnia odpowiednika In-App Updates. Aplikacja musi sama sprawdzić, czy jej wersja jest wspierana, pokazać własny ekran i odesłać użytkownika do strony aplikacji w App Store.
Popularny skrót to odpytywanie publicznego API App Store o najnowszą wersję. Mówi ono jednak tylko, jaka wersja jest najnowsza, a nie jaka jest minimalna. Odpowiedź bywa też opóźniona względem faktycznej publikacji, a w czasie phased release nowa wersja jest już w sklepie, choć jeszcze nie u wszystkich. Do prośby o aktualizację to wystarczy, ale do blokady potrzebujesz własnego źródła.
Własne źródło minimalnej wersji
Najprostsze i najbardziej przewidywalne rozwiązanie, które działa tak samo na obu platformach:
- Backend albo zdalna konfiguracja zwraca dwie wartości na platformę: minimalną wersję (poniżej — blokada) i zalecaną wersję (poniżej — prośba). Do tego opcjonalnie treść komunikatu.
- Aplikacja sprawdza je przy starcie i po powrocie z tła, zanim zrobi cokolwiek innego.
- Na Androidzie blokada może uruchomić tryb natychmiastowy In-App Updates, a na iOS własny ekran z przyciskiem prowadzącym do App Store.
Dodatkowo backend może sam rozpoznawać stare wersje. Aplikacja wysyła swoją wersję w nagłówku każdego zapytania, a backend dla niewspieranych wersji zwraca ustalony kod błędu, np. HTTP 426, który aplikacja zamienia na ekran aktualizacji. To zabezpieczenie na wypadek, gdyby sprawdzenie przy starcie z jakiegoś powodu nie zadziałało.
Jeśli korzystasz z Firebase Remote Config, pamiętaj o interwale pobierania. Domyślnie konfiguracja odświeża się najwyżej raz na 12 godzin, więc zmiana minimalnej wersji nie zadziała od razu. Do blokady lepszy jest własny, prosty endpoint albo Remote Config z krótszym interwałem dla tego jednego parametru.
Pułapki, które widzimy najczęściej
- Mechanizm dodany dopiero w wersji, która go potrzebuje. Wersje wydane wcześniej o nim nie wiedzą i nigdy nie pokażą ekranu aktualizacji. Dlatego minimalną wersję warto wdrożyć teraz, kiedy jeszcze nic się nie dzieje.
- Blokada przy błędzie sprawdzenia. Jeśli aplikacja nie może pobrać minimalnej wersji, bo serwer nie odpowiada, powinna wpuścić użytkownika. Inaczej awaria jednego endpointu zablokuje wszystkich, także tych z aktualną wersją. Jedynym wyjątkiem jest odpowiedź 426 z backendu, opisana wyżej.
- Użytkownik, który nie może zaktualizować. Jeśli nowa wersja wymaga nowszego Androida lub iOS, niż ma telefon, blokada zostawia go w ślepej uliczce. Google Play nawet nie pokaże mu aktualizacji. Ekran powinien wtedy wyjaśnić sytuację, a decyzję o podniesieniu minimalnego systemu warto podejmować świadomie — piszemy o tym w tekście o tym, dlaczego aplikacja nie działa na nowym Androidzie lub iOS.
- Porównywanie wersji jak tekstu. „1.10.0" jest nowsze niż „1.9.0", ale przy porównaniu znaków wychodzi odwrotnie. Wersje trzeba porównywać jako liczby albo po numerze kompilacji.
- Blokada przed zakończeniem wydania. Jeśli podniesiesz minimalną wersję, zanim nowa wersja trafi do wszystkich w sklepie, część użytkowników zobaczy ekran aktualizacji, a w sklepie nie będzie dla nich żadnej aktualizacji. Najpierw pełne wydanie, potem blokada.
- Brak ścieżki do sklepu. Przycisk musi prowadzić bezpośrednio na stronę aplikacji w App Store lub Google Play, a nie na stronę główną firmy.
Jak wprowadzić to w działającej aplikacji
- Sprawdź rozkład wersji w Play Console, analityce albo Crashlytics. To punkt wyjścia do każdej decyzji o blokadzie.
- Wydaj wersję z mechanizmem, ustawioną na razie tak, żeby nikogo nie blokowała. Monitoruj ją jak każde inne wydanie — więcej w tekście o monitoringu awarii aplikacji.
- Odczekaj, aż większość użytkowników przejdzie na tę wersję. Dopiero od tego momentu masz realną kontrolę nad tym, kto korzysta z aplikacji.
- Ustal zasady: kto i w jakich sytuacjach może podnieść minimalną wersję, jak długo trwa okres łagodnej prośby i jak wygląda komunikat. Warto to zapisać w umowie na utrzymanie aplikacji.
Wdrożenie podstawowego mechanizmu w aplikacjach na obie platformy i w backendzie to zwykle kilkanaście do kilkudziesięciu godzin pracy, zależnie od stanu projektu. To niewiele w porównaniu z sytuacją, w której stara wersja przestaje działać, a Ty nie masz jak dotrzeć do jej użytkowników. Jeśli zmiany w API planujesz razem z nowymi funkcjami, przeczytaj też, jak rozbudowywać istniejącą aplikację bez psucia starych wersji.
Podsumowanie
Minimalna wspierana wersja to ubezpieczenie: przez większość czasu nic nie robi, ale gdy jest potrzebna, nie da się jej dodać wstecz. Na Androidzie pomaga In-App Updates, na iOS trzeba zbudować własny ekran, a decyzja o tym, która wersja jest jeszcze wspierana, powinna należeć do Twojego backendu. Blokady używaj rzadko, poprzedzaj ją prośbą i nigdy nie blokuj użytkowników przy błędzie sprawdzenia.
Mechanizm aktualizacji jest jedną z pierwszych rzeczy, które dodajemy w aplikacjach przejmowanych w ramach utrzymania aplikacji mobilnych. Jeśli nie wiesz, czy Twoja aplikacja go ma i ile wersji działa dziś u użytkowników, zamów bezpłatną analizę aplikacji — wynik dostaniesz na piśmie.