10 min czytaniaFunkcje

Głębokie linki dla aplikacji mobilnych bez SDK

Universal Links + Android App Links pokrywają 80% przypadków użycia deep linkingu bez płatnego SDK. Dwa pliki asocjacyjne, kompromisy i przepisy na konkretne konfiguracje

Marius Voß
DevRel · edge infra
Ikona telefonu pokazująca przepływ głębokiego linku od klikniętego krótkiego linku do otwartej aplikacji z zestawionymi logo iOS Universal Links i Android App Links

Głęboki link to po prostu URL, który system operacyjny przekazuje do aplikacji zamiast do przeglądarki. Tapnij link na urządzeniu z zainstalowaną aplikacją - aplikacja otwiera się na właściwym ekranie. Tapnij go na urządzeniu bez aplikacji - przeglądarka podąża za przekierowaniem do webowego fallbacku. Jeden URL, dwa wyniki, bez shima JavaScript, bez potrzeby SDK third-party w większości konfiguracji.

Zespoły rutynowo przepłacają w tym obszarze. Branch.io, Adjust, AppsFlyer - ich materiały marketingowe eksponują odroczone głębokie linkowanie: tapujesz link przed zainstalowaniem aplikacji, instalujesz i aplikacja otwiera się dokładnie na treści, przez którą kliknąłeś. Ta funkcja jest naprawdę złożona i wymaga serwerowego fingerprintingu lub sztuczki z dopasowywaniem schowka, ponieważ routing linków OS jest uśpiony do momentu zainstalowania aplikacji. Jednak odroczone głębokie linkowanie to tylko jeden wycinek problemu. Bardziej powszechny przypadek - "link otwiera się w już zainstalowanej aplikacji" - jest w pełni rozwiązywany przez natywne prymitywy OS, które Apple i Google wypuścili odpowiednio w 2015 i 2015–16, działające bez niczego poza domeną, którą kontrolujesz, i dwoma plikami JSON.

Ten artykuł jest o tych dwóch plikach JSON.

TL;DR#

  • Apple Universal Links (iOS 9+) i Android App Links (Android 6.0+) obsługują przepływ "otwórz w aplikacji jeśli zainstalowana, webowy fallback jeśli nie" bez SDK third-party.
  • Oba wymagają domeny, którą kontrolujesz, serwowanej przez HTTPS z zwalidowanym plikiem asocjacyjnym pod /.well-known/. OS pobiera i buforuje plik podczas instalacji aplikacji, nie przy każdym tapnięciu.
  • Skracacz URL z domeną niestandardową jak go.acme.example serwuje oba pliki i staje się linkiem wyzwalającym routing aplikacji - krótki link to głęboki link.
  • Co SDK dodaje, czego nie dostarczają prymitywy OS: odroczone głębokie linkowanie, probabilistyczna atrybucja instalacji i łączenie tożsamości między platformami. Jeśli tego potrzebujesz, SDK uzasadnia swój koszt. Jeśli nie, płacisz za funkcje, których nie używasz.

Natywne prymitywy OS#

Apple wprowadził Universal Links w iOS 9 (2015). Android wypuścił App Links w Android 6.0 Marshmallow (również 2015, wydany na urządzenia przez 2016). Oba stosują ten sam model konceptualny: OS twierdzi zweryfikowaną relację między domeną a aplikacją i gdy URL na tej domenie jest tapowany, OS kieruje go do aplikacji zamiast do przeglądarki.

Weryfikacja jest wzajemna i offline-first. Podczas instalacji aplikacji OS pobiera plik asocjacyjny z Twojej domeny i buforuje go. Fetcherowi Apple poświęcona jest dokumentacja na developer.apple.com/ios/universal-links/ (dostęp 2026-05-12); odpowiednik Google dostępny jest na developer.android.com/training/app-links (dostęp 2026-05-12). Żadne pobranie nie odbywa się w momencie tapnięcia na rozgrzanym urządzeniu - cache oznacza, że decyzja routingowa kosztuje zero sieciowych round-tripów.

Samo przekierowanie to standardowe HTTP 302. OS przechwytuje je zanim przeglądarka załaduje stronę, sprawdza swój lokalny cache i przekazuje URL do aplikacji, jeśli znajdzie dopasowanie. Gdy cache jest rozgrzany, cała decyzja jest lokalna. Edge serwujący krótki link wydaje przekierowanie i OS przejmuje kontrolę.

Dwa pliki#

apple-app-site-association#

Plik AASA musi być serwowany pod adresem https://twojadomena.example/.well-known/apple-app-site-association (Apple sprawdza też ścieżkę apex https://twojadomena.example/apple-app-site-association dla zgodności z poprzednimi wersjami, ale ścieżka .well-known to aktualny standard). Musi być serwowany przez HTTPS z ważnym łańcuchem certyfikatów i z nagłówkiem Content-Type: application/json. Fetcher CDN Apple odrzuca pliki serwowane z niepoprawnym Content-Type - to jeden z częstszych błędów konfiguracyjnych w produkcji.

Pełna dokumentacja formatu znajduje się na developer.apple.com/documentation/xcode/supporting-associated-domains.

Minimalna struktura AASA:

{
  "applinks": {
    "details": [
      {
        "appIDs": ["ABCDE12345.com.example.acme"],
        "components": [
          {
            "/": "/spring-*",
            "comment": "Dopasuj każdą ścieżkę zaczynającą się od /spring-"
          },
          {
            "/": "/campaigns/*"
          }
        ]
      }
    ]
  }
}

appIDs to połączenie Twojego Apple Team ID i identyfikatora pakietu aplikacji, oddzielone kropką. Tablica components kontroluje, które ścieżki wyzwalają routing aplikacji; wszystko, co nie pasuje do komponentu, trafia do przeglądarki. Możesz zarejestrować wiele aplikacji w tablicy details - przydatne, jeśli masz wersję konsumencką i enterprise tego samego produktu na tej samej domenie.

Jeden szczegół wart wyraźnego zaznaczenia: "/" z wzorcem wieloznacznym jak /spring-* to dopasowanie prefiksu ścieżki. Parser AASA Apple obsługuje składnię wzorców zdefiniowaną w dokumentacji Xcode, w tym * (dowolny podciąg), ? (dowolny pojedynczy znak) i obiekty wykluczenia. Jeśli chcesz dopasować każdą ścieżkę na domenie, użyj "/" : "/*". Jeśli chcesz wykluczyć konkretną ścieżkę z routingu aplikacji - powiedzmy, że Twoja strona /account/delete powinna zawsze otwierać się w przeglądarce - dodaj obiekt wykluczenia przed wieloznacznikiem:

{
  "/": "/account/delete",
  "exclude": true
}

Reguły są oceniane od pierwszej do ostatniej. Umieszczaj wykluczenia przed wieloznacznikami.

assetlinks.json#

Plik Android Digital Asset Links znajduje się pod https://twojadomena.example/.well-known/assetlinks.json. Specyfikacja jest utrzymywana przez Google na developers.google.com/digital-asset-links/v1/getting-started.

[
  {
    "relation": ["delegate_permission/common.handle_all_urls"],
    "target": {
      "namespace": "android_app",
      "package_name": "com.example.acme",
      "sha256_cert_fingerprints": [
        "AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99"
      ]
    }
  }
]

package_name to identyfikator aplikacji w Play Store. sha256_cert_fingerprints to odcisk palca SHA-256 certyfikatu użytego do podpisania APK - nie SHA-1, nie MD5. Odcisk palca znajdziesz w Play Console pod App Integrity lub uruchamiając keytool -list -v -keystore your.keystore. Jeśli wydajesz zarówno build debug, jak i produkcyjny, dołącz oba odciski palca do tablicy.

W odróżnieniu od pliku AASA, plik asocjacyjny Androida nie obsługuje filtrowania ścieżek na poziomie pliku. Dopasowanie ścieżek dla App Links odbywa się w AndroidManifest.xml przez <intent-filter> z android:pathPrefix, android:pathPattern lub nowszym android:pathAdvancedPattern (dostępnym od Android 12). Plik assetlinks.json potwierdza własność domeny; manifest deklaruje, które ścieżki obsługuje aplikacja.

Sekwencja rozwiazywania AASA: tapniecie krotkiego linku, pobranie przez OS przy pierwszej instalacji, trafienie w cache przy kolejnych tapnięciach

Jak skracacz URL się tu wpisuje#

Krótki link jak go.acme.example/spring-launch to po prostu URL na domenie. Z perspektywy OS, jeśli go.acme.example ma ważny plik AASA lub assetlinks.json, każde tapnięcie linku pod tą domeną kwalifikuje się do routingu aplikacji.

To jest konfiguracja, którą bezpośrednio wspieramy na domenach niestandardowych z Elido. Gdy rejestrujesz go.acme.example jako domenę niestandardową w swoim workspace, Elido serwuje przekierowanie HTTPS dla każdego slug pod tą domeną. Serwujesz dwa pliki asocjacyjne z tej samej domeny - albo z własnego origin za proxy ścieżki, albo przez własny serwer HTTPS domeny. Przekierowanie edge jest uruchamiane; OS przechwytuje je zanim przeglądarka załaduje stronę, konsultuje swój cache AASA/App Links i otwiera aplikację, jeśli znajdzie dopasowanie.

Architektura jest opisana bardziej szczegółowo w artykule o niestandardowych krótkich linkach z własną domeną - wystawianie TLS i konfiguracja CNAME mają tu zastosowanie dokładnie tak jak tam opisano. Warstwa głębokiego linkowania jest addytywna: ta sama domena, to samo przekierowanie, dwa pliki JSON na wierzchu.

Dla zespołów produktowych używających krótkich linków do mobile onboardingu - kody polecające, linki zaproszeniowe, przepływy "udostępnij przepis" - ten wzorzec pokrywa prawie wszystko bez dodawania zależności SDK do pliku binarnego aplikacji.

Co dodaje SDK#

Trzy możliwości, których natywne prymitywy OS nie zapewniają:

Odroczone głębokie linkowanie. Użytkownik tapuje Twój link przed zainstalowaniem aplikacji. Przy pierwszym uruchomieniu po instalacji aplikacja otwiera się na dokładnej treści, przez którą kliknął. iOS Universal Links i Android App Links są nieme, gdy aplikacja nie jest zainstalowana - URL trafia do przeglądarki, intencja jest utracona. Jej odzyskanie wymaga serwerowego dopasowania odcisku palca (IP + User-Agent + timestamp, probabilistyczne) lub sztuczki ze schowkiem iOS. Branch, Adjust i AppsFlyer oba to implementują; przypadki brzegowe dotyczące promptów App Tracking Transparency i zachowania Safari sprawiają, że samodzielna implementacja nie jest prosta.

Atrybucja instalacji na dużą skalę. Natywna ścieżka OS daje Ci otwarcie aplikacji z ścieżką URL, ale jeśli aplikacja nie była zainstalowana przy pierwszym tapnięciu, łańcuch atrybucji jest przerwany. Uzgadnianie kliknięć z instalacjami przez SKAN na iOS i Play Install Referrer na Android jest możliwe bez płatnego SDK, ale wymaga integracji, którą dostawcy atrybucji już wykonali.

Łączenie tożsamości między platformami. Łączenie tapnięcia z adresem e-mail, kontaktem CRM lub sesją webową. Natywna ścieżka OS jest anonimowa z perspektywy serwisu linków. Dostawcy SDK utrzymują trwały graf urządzeń. Budowanie tego samodzielnie to poważny projekt infrastruktury danych.

Jeśli żadne z tych trzech nie ma zastosowania, prymitywy OS Cię pokrywają. Jeśli jedno z nich jest istotne, ustal jego zakres precyzyjnie - możesz potrzebować tylko odroczonych głębokich linków, jednej powierzchni API, nie pełnego SDK.

Macierz funkcji: natywne prymitywy OS i platny SDK otwieraja aplikacje i zapewniaja webowy fallback, ale tylko SDK dodaje odroczone gleboke linkowanie, atrybucje instalacji per klikniecie i graph tożsamosci miedzyplatformowej.

Przepisy konfiguracyjne#

Wymagania DNS i HTTPS#

Oba pliki muszą być serwowane przez HTTPS z domeny, której linki chcesz głęboko linkować. Certyfikat musi być zakorzeniony w publicznym CA; certyfikaty self-signed powodują, że walidacyjne fetchery Apple i Google zawodzą po cichu. Certyfikaty Let's Encrypt działają bez problemów.

TLS domeny nie może też przekierowywać ścieżki /.well-known/ przed serwowaniem pliku. Jeśli Twój serwer wydaje przekierowanie www. zanim fetcher Apple może dotrzeć do https://twojadomena.example/.well-known/apple-app-site-association, pobranie nie powiedzie się. Fetcher Apple podąża za co najwyżej jednym przekierowaniem, ale fetcher assetlinks Google w ogóle nie podąża za przekierowaniami - plik musi być pod dokładną ścieżką, bez przekierowania.

iOS: uprawnienie Associated Domains#

W Xcode, w sekcji Signing & Capabilities swojego targetu, dodaj uprawnienie Associated Domains z wartością applinks:go.acme.example. Jeśli testujesz na buildzie deweloperskim (nie dystrybuowanym przez TestFlight lub App Store), dodaj ?mode=developer do wartości uprawnienia: applinks:go.acme.example?mode=developer. Informuje to OS, aby ponownie pobierał AASA przy każdym uruchomieniu zamiast używać cache z czasu instalacji - przydatne przy iterowaniu na wzorcach ścieżek bez konieczności ponownej instalacji ze Store za każdym razem.

CDN Apple, który pobiera Twój plik AASA, to własna infrastruktura Apple, nie urządzenie użytkownika końcowego. Apple wstępnie pobiera i buforuje pliki AASA z Twojej domeny i dostarcza je urządzeniom podczas instalacji aplikacji, co oznacza, że plik musi być dostępny przez crawlery Apple, nie tylko przez urządzenie użytkownika końcowego. Oznacza to również opóźnienie propagacji - zmiany w pliku AASA mogą trwać godziny zanim dotrą do wszystkich urządzeń przez cache Apple. Dla deweloperów potrzebujących szybkiej iteracji na wzorcach ścieżek, uprawnienie ?mode=developer omija CDN Apple i pobiera bezpośrednio z Twojego serwera.

W AndroidManifest.xml, wewnątrz activity, która powinna obsługiwać głębokie linki:

<intent-filter android:autoVerify="true">
  <action android:name="android.intent.action.VIEW" />
  <category android:name="android.intent.category.DEFAULT" />
  <category android:name="android.intent.category.BROWSABLE" />
  <data
    android:scheme="https"
    android:host="go.acme.example"
    android:pathPrefix="/campaigns/" />
</intent-filter>

android:autoVerify="true" mówi Androidowi, aby próbował weryfikacji domeny względem assetlinks.json. Bez tego przy każdym tapnięciu użytkownik widzi arkusz disambiguacji zamiast bezpośredniego otwarcia aplikacji. Weryfikacja odbywa się podczas instalacji; urządzenie łączy się z https://go.acme.example/.well-known/assetlinks.json i sprawdza, czy odcisk palca certyfikatu zainstalowanej aplikacji jest wymieniony.

Walidatory i typowe błędy#

Apple udostępnia walidator na search.developer.apple.com/appsearch-validation-tool/, który sprawdza, czy CDN Apple może pobrać i sparsować Twój plik AASA. Wpisz swoją domenę, a zwróci albo wynik poprawnego parsowania, albo konkretny błąd. Typowe niepowodzenia:

  • Niepoprawny Content-Type. Jeśli Twój serwer zwraca text/plain lub application/octet-stream, walidator zgłasza plik jako nieczytelny, nawet jeśli JSON jest poprawny. Ustaw Content-Type: application/json jawnie.
  • Brakujące lub niedopasowane appIDs. Prefiks Team ID w appIDs musi dokładnie odpowiadać Team ID w Twoim koncie Apple Developer, z uwzględnieniem wielkości liter. Jeden błędny znak zawodzi po cichu w momencie tapnięcia.
  • Problem z łańcuchem certyfikatów. Jeśli Twoja domena serwuje certyfikat niezakorzeniony w publicznym CA (powszechne w środowiskach stagingowych z lokalnymi korzeniami CA), fetcher Apple odrzuca plik.

Walidator Google to Digital Asset Links API: https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://go.acme.example&relation=delegate_permission/common.handle_all_urls. Odpowiedź JSON zawiera listę wszystkich stwierdzeń, które Google zweryfikował dla Twojej domeny. Jeśli odpowiedź jest pusta lub nie zawiera Twojej nazwy pakietu, Android nie zweryfikuje automatycznie aplikacji podczas instalacji. Typowe niepowodzenia:

  • Przekierowanie na ścieżce assetlinks. Jak wspomniano: fetcher Google nie podąża za przekierowaniami.
  • Niepoprawny odcisk palca certyfikatu. APK debug i APK release są podpisywane różnymi kluczami. Jeśli wymieniłeś tylko odcisk palca release, buildy debug nie zweryfikują się. Wymień oba.
  • Plik serwowany z CORS, ale z niepoprawnym nagłówkiem dla żądania weryfikacji. Fetcher nie dba o CORS, ale niektóre konfiguracje CDN zwracają 403 na GET z zakresu IP Google, jeśli ścieżka nie jest na liście dozwolonych cache. Sprawdź, czy /.well-known/assetlinks.json zwraca 200 z zewnętrznego klienta HTTP, a nie tylko z Twojej przeglądarki.

Kompromis wyrażony wprost#

Usunięcie SDK głębokiego linkowania oszczędza około 150–250KB skompresowanego rozmiaru pliku binarnego i eliminuje wywołanie API per-instalacja do serwerów dostawcy atrybucji. Usuwa to relację udostępniania danych z Twojej polityki prywatności i może uprościć rejestry przetwarzania danych RODO. Rzeczywiste korzyści, choć skromne.

Kosztem jest to, że atrybucja w czasie instalacji staje się przybliżona lub nieobecna. Jeśli użytkownik tapuje Twój link przed zainstalowaniem aplikacji, zobaczysz instalację w App Store Connect lub Play Console, ale nie powiążesz jej z konkretnym tapnięciem linku. Nadal możesz uruchamiać eksperymenty ze smart linkami, aby porównać, które kampanie generują więcej instalacji - sygnały względne przetrwają - ale atrybucja per-urządzenie, per-kliknięcie wymaga warstwy fingerprintingu SDK.

Dla zespołów na wczesnym etapie skalowania, gdzie CPI per-kanał nie kieruje jeszcze decyzjami budżetowymi, zaczynanie od prymitywów OS jest rozsądną ścieżką. Dodaj SDK atrybucji później, gdy dane będą naprawdę wykonalne.

Porownanie przed i po usunięciu SDK glebokiego linkowania: zaoszczędzone 150–250KB pliku binarnego i mniej przeplywow danych po prawej stronie, z drugiej strony utrata atrybucji instalacji per klikniecie, ktora staje sie przyblizena.

Dla przewodnika konfiguracji deep link Elido skierowanego do deweloperów - pełny schemat przepływu weryfikacji domeny, konfiguracja proxy AASA i opcje serwowania assetlinks.json są tam udokumentowane. Strona rozwiązań dla zespołów produktowych omawia szersze przypadki użycia smart linków i linkowania mobilnego.


Marius Voß jest DevRel + edge infra w Elido. Jest właścicielem serwisów edge-redirect i domain-manager.

Wypróbuj Elido

Wklej URL, otrzymaj krótki link

Bez rejestracji. Link działa 30 dni. Zarejestruj się, aby zachować go na zawsze.

Za darmo, bez rejestracji · 2 dziennie

Wypróbuj Elido

Skracarka URL hostowana w UE: własne domeny, głęboka analityka i otwarte API. Darmowy plan - bez karty kredytowej.

Tagi
mobile deep linking
universal links
app links android
deep linking without sdk
apple app site association
digital asset links

Czytaj dalej