Universal Link to mechanizm Apple (iOS 9+), który umożliwia otwieranie linków internetowych bezpośrednio w aplikacji, z pominięciem Safari. Jeśli aplikacja nie jest zainstalowana, link bezszwowo otwiera się w przeglądarce. Termin został wprowadzony przez Apple w 2015 roku na WWDC jako część Handoff i ekosystemu Continuity. Według Apple Developer, Universal Link zapewnia jednolite doświadczenie użytkownika między siecią a aplikacją natywną bez okien dialogowych wyboru.
Najważniejsze
Universal Link to standardowy link HTTPS postaci https://example.com/page, który po kliknięciu z urządzenia iOS otwiera zainstalowaną aplikację zamiast Safari. Główna różnica w stosunku do Custom URL Scheme: Universal Link nie wymaga rejestracji niestandardowego schematu (myapp://) — używana jest zwykła domena. Eliminuje to problem URL Scheme hijacking, gdzie każda aplikacja może zarejestrować ten sam schemat.
Apple przedstawiło Universal Link na WWDC 2015 w ramach iOS 9. Mechanizm stał się częścią ekosystemu Handoff i Spotlight: Universal Link działa nie tylko w przeglądarce, ale także w wynikach wyszukiwania Spotlight, w Mail, Messages i innych aplikacjach systemowych. Ponadto Universal Link jest obsługiwany w watchOS i macOS — użytkownik może otworzyć aplikację na iPhonie przez link na Macu.
Kluczowa zaleta: jeden URL. Deweloper nie zarządza dwoma różnymi linkami (jednym dla sieci, drugim dla aplikacji). Universal Link to ten sam link https. Jeśli aplikacja jest zainstalowana — otwiera się ona. Jeśli nie — ten sam link otwiera się w Safari jako zwykła strona internetowa. Zapewnia to idealny fallback bez utraty ruchu.
Mechanizm Universal Link składa się z trzech etapów: weryfikacja asocjacji, przetwarzanie linku i fallback do przeglądarki. Każdy etap jest krytyczny dla poprawnego działania. Jeśli asocjacja nie jest skonfigurowana, iOS traktuje link jako zwykłe przejście do Safari. Przyjrzyjmy się każdemu etapowi szczegółowo.
Przy pierwszym kliknięciu w link iOS pobiera plik apple-app-site-association z serwera pod adresem https://example.com/.well-known/apple-app-site-association. Plik zawiera JSON z identyfikatorem Team ID i Bundle ID aplikacji, a także listę ścieżek, które aplikacja powinna otwierać. iOS buforuje ten plik i okresowo sprawdza jego aktualność (przy aktualizacji aplikacji, ponownym uruchomieniu urządzenia).
Plik JSON apple-app-site-association musi być dostępny przez HTTPS bez przekierowań. Serwer musi zwracać Content-Type: application/json. Ważne: plik nie ma rozszerzenia .json — iOS szuka go ściśle pod ścieżką /.well-known/apple-app-site-association. Apple zaleca również dodanie obsługi Universal Link w CDN i sprawdzenie, czy plik nie jest blokowany przez robots.txt.
// apple-app-site-association — minimalna konfiguracja
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TEAMID.com.example.app",
"paths": ["/product/*", "/profile/*", "/search"]
}
]
}
}
appID jest tworzony jako Team ID + Bundle ID (TEAMID.com.example.app). paths — tablica wzorców URL, które aplikacja powinna obsługiwać. Można używać *, ? i notacji NOT: ["NOT /admin/*", "/product/*"]. Ścieżki są sprawdzane w kolejności wyliczenia: pierwsze dopasowanie określa zachowanie. Jeśli ścieżka nie pasuje — link otwiera się w Safari.
Po pomyślnej weryfikacji asocjacji iOS przekazuje link do aplikacji. Obsługa odbywa się w AppDelegate przez metodę application(_:continue:restorationHandler:) dla NSUserActivity lub w SceneDelegate przez scene(_:continue:). Deweloper otrzymuje obiekt NSUserActivity z typem NSUserActivityTypeBrowsingWeb, wyodrębnia URL i nawiguje do odpowiedniego ekranu.
// Obsługa Universal Link w AppDelegate
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping UIUserActivityRestorationHandler
) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL
else { return false }
// Nawigacja do ekranu zgodnie z URL
DeepLinkRouter.navigate(to: url)
return true
}
DeepLinkRouter w powyższym przykładzie to niestandardowa klasa, która parsuje URL i wywołuje odpowiedni koordynator nawigacji. Dla SwiftUI obsługa odbywa się przez metodę onOpenURL lub modyfikator environment(\.openURL). Ważne jest obsłużenie nie tylko uruchomienia na pierwszym planie (foreground), ale także przypadku, gdy aplikacja nie była uruchomiona (cold start): Universal Link w tym przypadku otwiera aplikację przez opcje uruchamiania.
Jeśli aplikacja nie jest zainstalowana, iOS automatycznie otwiera Universal Link w Safari. To kluczowa różnica w stosunku do Custom URL Scheme: użytkownik nie widzi błędu. Fallback to standardowa strona internetowa tej samej domeny. Deweloper może umieścić na tej stronie link do App Store, informacje o produkcie lub alternatywną treść.
Ważne: fallback nie może być dostosowywany na poziomie iOS. iOS po prostu otwiera URL w Safari. Aby wyświetlać różną treść dla użytkowników z zainstalowaną i niezainstalowaną aplikacją, użyj Smart App Banner (meta-tag dla Safari proponujący otwarcie aplikacji) lub JavaScript do wykrywania instalacji aplikacji. Apple udostępnia również SKAdNetwork do atrybucji instalacji przez Universal Link.
Universal Link i tradycyjny Deep Link (Custom URL Scheme) rozwiązują to samo zadanie, ale zasadniczo różnią się architekturą i bezpieczeństwem. Custom URL Scheme — niestandardowy protokół (myapp://), który rejestruje się w Info.plist. Każda aplikacja może zarejestrować ten sam schemat (myapp://), a iOS nie może określić, która z nich jest „prawdziwa”. Nazywa się to URL Scheme hijacking.
Universal Link rozwiązuje problem hijackingu przez weryfikację domeny. Tylko właściciel domeny może umieścić apple-app-site-association na swoim serwerze, potwierdzając powiązanie z konkretnym Bundle ID. Dwie aplikacje nie mogą zarejestrować jednego Universal Link: jeśli wystąpi konflikt, iOS nadaje priorytet aplikacji zainstalowanej jako ostatnia lub otwiera Safari.
Inna różnica: Fallback. Custom URL Scheme nie ma fallbacku — jeśli aplikacja nie jest zainstalowana, przeglądarka pokazuje błąd. Universal Link otwiera stronę. Jeden URL oznacza, że wartość SEO linku zostaje zachowana (link jest indeksowany przez Google), a użytkownik z dowolnym urządzeniem otrzymuje odpowiednią treść. Universal Link to ewolucyjny krok od deep link do unified link.
| Cecha | Custom URL Scheme | Universal Link |
|---|---|---|
| Format | myapp://path | https://domain/path |
| Weryfikacja | Nie | apple-app-site-association |
| Bezpieczeństwo | Podatny na hijacking | Tylko właściciel domeny |
| Fallback | Błąd | Strona w Safari |
| Wersja iOS | iOS 3+ | iOS 9+ |
Konfiguracja Universal Link obejmuje część serwerową i kliencką. Część serwerowa — umieszczenie pliku apple-app-site-association pod adresem https://domain/.well-known/apple-app-site-association. Część kliencka — rejestracja domeny w Associated Domains w Xcode (Capabilities → Associated Domains → applinks:example.com). Następnie aplikacja automatycznie otrzymuje wszystkie Universal Link dla określonej domeny.
Kroki konfiguracji:
Debugowanie Universal Link — częsty ból głowy deweloperów iOS. Główne przyczyny niedziałających linków: plik apple-app-site-association niedostępny przez HTTPS, nieprawidłowy appID, Content-Type nie application/json, przekierowanie ze ścieżki /.well-known, buforowanie starej wersji pliku (reset przez Settings → Developer → Associated Domains Development). Apple udostępnia narzędzie „Validation Checker" w Apple Developer Console do testowania asocjacji.
Branch i inne platformy MMP upraszczają konfigurację Universal Link: generują one apple-app-site-association automatycznie i hostują go na swojej domenie. Deweloper wystarczy dodać domenę Branch w Associated Domains i zintegrować SDK. Jest to szczególnie wygodne dla startupów, które nie mają własnej infrastruktury serwerowej do hostingu pliku AASA.
Universal Link ma kilka ograniczeń. Po pierwsze: plik apple-app-site-association musi być dostępny ściśle przez HTTPS (HTTP nie jest obsługiwane). Po drugie: link musi prowadzić do tej samej domeny, która jest określona w Associated Domains. Międzydomenowe Universal Link nie działają — dla każdej domeny potrzebny jest osobny wpis w Capabilities i osobny plik AASA. Po trzecie: Universal Link nie działa w WKWebView — tylko w Safari i komponentach systemowych.
Kompatybilność: iOS 9.0+ (Universal Link), watchOS 6.0+ (Handoff Universal Link), macOS 10.15+ (Catalyst i aplikacje Mac). W starszych wersjach iOS link otwiera się w Safari. Oznacza to, że na iOS 8 (mniej niż 1% urządzeń) Universal Link nie zadziała. Zaleca się obsługę również Custom URL Scheme jako fallback dla starszych urządzeń, jeśli odbiorcy obejmują użytkowników z przestarzałymi wersjami.
iOS 16+ zmiany: Apple ulepszyło obsługę Universal Link dla SwiftUI. Pojawił się nowy modyfikator environment(\.openURL) z możliwością opóźnionego przetwarzania. iOS 16 umożliwia również otwieranie Universal Link w aplikacji nawet przez SFSafariViewController. Dla użytkowników iOS 16 zaleca się całkowite przejście na obsługę Universal Link w SwiftUI, pozostawiając kod AppDelegate tylko dla wstecznej kompatybilności.
Często zadawane pytania
Universal Link używa standardowego HTTPS-URL i jest weryfikowany przez plik na serwerze. Custom URL Scheme używa niestandardowego protokołu (myapp://) bez weryfikacji, co czyni go podatnym na przechwycenie przez inną aplikację, która zarejestrowała ten sam schemat.
Plik umieszcza się w katalogu głównym serwera HTTPS pod ścieżką /.well-known/apple-app-site-association (bez rozszerzenia .json). Serwer musi zwracać Content-Type: application/json. Ważne: żadnych przekierowań, plik musi być dostępny bezpośrednio.
Główne przyczyny: nieprawidłowy Team ID lub Bundle ID w pliku AASA, plik niedostępny przez HTTPS, przekierowanie, nieprawidłowy Content-Type, buforowanie starej wersji. Sprawdź przez Developer → Associated Domains Development i zresetuj pamięć podręczną przez ponowne uruchomienie urządzenia.
Nie — Universal Link wymaga serwera HTTPS, na którym umieszczony jest apple-app-site-association. Bez domeny Universal Link nie działa. Alternatywa: Custom URL Scheme (mniej bezpieczne) lub usługi zewnętrzne (Branch, Firebase) z własną domeną.
Nie — Universal Link to ekskluzywna technologia Apple dla iOS, iPadOS, watchOS i macOS. Na Androidzie odpowiednik nazywa się App Link (Android 6.0+), który używa Digital Asset Links (assetlinks.json) zamiast apple-app-site-association.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również