Wszystkie artykuły
mobiledeep linksiOSAndroid

Testowanie mobilnych deep linków z tunelem localhost

Universal Links na iOS i App Links na Androidzie wymagają pliku JSON serwowanego przez HTTPS w katalogu głównym twojej domeny. iOS chce /.well-known/apple-app-site-association. Android chce /.well-known/assetlinks.json. localhost nie może serwować żadnego po nazwie hosta, którą system skojarzy z twoją aplikacją. Więc tunelujemy.

Faktyczny wymóg na każdej platformie

iOS Universal Links

System pobiera https://twoja-domena.com/.well-known/apple-app-site-association (lub /apple-app-site-association) gdy aplikacja jest instalowana. Sprawdza zawartość względem entitlement associated-domains twojej aplikacji. Pobranie musi się udać przez prawdziwe HTTPS. iOS nie ufa do tego certyfikatom self-signed ani localhost.

Android App Links

Android weryfikuje App Links pobierając https://twoja-domena.com/.well-known/assetlinks.json. Plik musi wymieniać fingerprinty SHA-256 twojej aplikacji. Weryfikacja dzieje się przy instalacji i pierwszym uruchomieniu. To samo ograniczenie: prawdziwe HTTPS, prawdziwa domena.

Dlaczego localhost nie może tego bezpośrednio

Nawet gdy mkcert daje ci zaufane HTTPS w przeglądarce laptopa, mobilny system nie ufa twojemu lokalnemu CA. A domena w twoim apple-app-site-association musi pasować do associated-domain w entitlement aplikacji — to prawdziwa, rozwiązywalna przez DNS domena, nie localhost.

Niektóre zespoły obchodzą to dedykowaną domeną staging. To działa, ale pętla iteracji jest powolna. Tunel localhost daje prawdziwy URL HTTPS na prawdziwej subdomenie, którą urządzenia mobilne osiągają bez narzekania.

Jak to podłączyć

  1. Serwuj swój apple-app-site-association i assetlinks.json z lokalnego serwera dev pod /.well-known/. Oba pliki. Obie trasy.
  2. Wykonaj npx portpreview 3000 (lub port, którego używa twój serwer dev).
  3. Zanotuj nazwę hosta tunelu — coś jak abc123.portpreview.dev.
  4. W entitlement associated-domains twojej aplikacji iOS dodaj applinks:abc123.portpreview.dev. W intent filter Androida ten sam host.
  5. Zbuduj i zainstaluj aplikację na prawdziwym urządzeniu (symulatory mają dziwne zachowanie Universal Link).
  6. Otwórz URL z innej aplikacji — Notatki, Mail, kod QR — i obserwuj, jak kieruje do twojej zainstalowanej aplikacji zamiast przeglądarki.

Haczyk tunelowania dla deep linków: nazwa hosta tunelu zmienia się między sesjami, chyba że masz zarezerwowaną subdomenę. Każda rotacja oznacza przebudowę aplikacji z nowym wpisem associated-domain. Jeśli często iterujesz zachowanie deep linków, zdobądź zarezerwowaną subdomenę.

Content-type ma znaczenie dla apple-app-site-association

iOS oczekuje pliku bez rozszerzenia i albo content-type application/json (nowsze iOS), albo application/pkcs7-mime (starszy, podpisany format). Niemal wszystkie nowoczesne aplikacje używają wariantu czystego JSON. Upewnij się, że twój serwer dev zwraca właściwy content-type, inaczej iOS po cichu odrzuca plik bez użytecznego błędu.

Przetestuj najpierw z przeglądarki desktopowej: otwórz https://twoj-tunel.portpreview.dev/.well-known/apple-app-site-association i potwierdź, że JSON się renderuje, a nagłówek content-type w dev tools jest poprawny. Jeśli jest źle, napraw przed ściganiem bugów Universal Link w symulatorze.

Inne pułapki debugowania deep linków

Niezgodność entitlement aplikacji

Jeśli twój entitlement associated-domains mówi applinks:abc.portpreview.dev, ale apple-app-site-association wymienia def.portpreview.dev, iOS nie pobiera. Nazwa hosta musi być spójna.

Universal Link z wnętrza Safari

Stuknięcie Universal Link wewnątrz Safari (tej samej aplikacji, w której jest karta) czasem otwiera w Safari zamiast aplikacji. To celowe — iOS zapobiega sztuczce "otwórz aplikację gdy użytkownik kliknie link". Testuj z Notatek lub Mail.

Android App Links i digital asset links

Android obsługuje też niestandardowe schematy URL (twojaaplikacja://sciezka), które nie potrzebują HTTPS ani assetlinks.json. Łatwiejsze do testowania, ale mniej bezpieczne — każda aplikacja może zarejestrować ten sam schemat. Dla deep linkingu jakości produkcyjnej odpowiedzią są App Links.

Przepływ testowania mobilnego, którego używamy

Dla projektu dostarczającego iOS i Android z deep linkami:

  1. Uruchom backend serwujący pliki .well-known.
  2. Tuneluj go z npx portpreview 3000.
  3. Gdy URL tunelu jest stabilny dla sesji (lub użyj zarezerwowanej subdomeny), zaktualizuj wpisy associated-domain aplikacji i zbuduj.
  4. QA na fizycznych urządzeniach — zarówno świeże instalacje, jak i aktualizacje.
  5. Dla kombinacji OAuth-i-deep-link (dostawcy logowania przekierowujący z powrotem do aplikacji) połącz to z testowaniem callbacków OAuth.

Konfiguracja jest irytująca za pierwszym razem. Potem URL tunelu to tylko kolejna zmienna środowiskowa w schemacie Xcode i Gradle.

Po szersze wzorce testowania mobilnego zobacz testowanie mobilne z tunelem localhost. Dołącz do listy oczekujących PortPreview.

Najczęściej zadawane pytania

Czy mogę testować iOS Universal Links na localhost?
Nie bezpośrednio. Universal Links wymagają, by iOS pobierał apple-app-site-association przez prawdziwe HTTPS z prawdziwej domeny. localhost się nie kwalifikuje. Tunel daje URL HTTPS na subdomenie tunelu, którą iOS skojarzy z twoją aplikacją, gdy umieścisz ją w entitlement associated-domains.
Jakiego content-type powinien używać apple-app-site-association?
Nowoczesny iOS oczekuje application/json. Starsze wersje akceptowały też application/pkcs7-mime dla podpisanych plików. Większość aplikacji dziś używa wariantu czystego JSON. Jeśli iOS nie pobiera twojego pliku, sprawdź najpierw nagłówek content-type z przeglądarki desktopowej.
Czy Android App Links potrzebują tunelu do testów lokalnych?
Tak, jeśli chcesz pełnej weryfikacji App Link (nie niestandardowych schematów URL). Android pobiera assetlinks.json przez prawdziwe HTTPS z domeny w twoim intent filter. Tunel dostarcza prawdziwy URL HTTPS na domenie, którą urządzenie może zweryfikować. Niestandardowe schematy tego nie potrzebują, ale są mniej bezpieczne.