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ć
- Serwuj swój
apple-app-site-associationiassetlinks.jsonz lokalnego serwera dev pod/.well-known/. Oba pliki. Obie trasy. - Wykonaj
npx portpreview 3000(lub port, którego używa twój serwer dev). - Zanotuj nazwę hosta tunelu — coś jak
abc123.portpreview.dev. - W entitlement associated-domains twojej aplikacji iOS dodaj
applinks:abc123.portpreview.dev. W intent filter Androida ten sam host. - Zbuduj i zainstaluj aplikację na prawdziwym urządzeniu (symulatory mają dziwne zachowanie Universal Link).
- 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:
- Uruchom backend serwujący pliki
.well-known. - Tuneluj go z
npx portpreview 3000. - Gdy URL tunelu jest stabilny dla sesji (lub użyj zarezerwowanej subdomeny), zaktualizuj wpisy associated-domain aplikacji i zbuduj.
- QA na fizycznych urządzeniach — zarówno świeże instalacje, jak i aktualizacje.
- 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.