Universal Link este un mecanism Apple (iOS 9+) care permite deschiderea linkurilor web direct în aplicație, ocolind Safari. Dacă aplicația nu este instalată, linkul se deschide fără probleme în browser. Termenul a fost introdus de Apple în 2015 la WWDC ca parte a Handoff și a ecosistemului Continuity. Potrivit Apple Developer, Universal Link asigură o experiență unitară între web și aplicația nativă fără dialoguri de selecție.
Principalele puncte
Universal Link este un link HTTPS standard de forma https://example.com/page care, la accesarea de pe un dispozitiv iOS, deschide aplicația instalată în locul Safari. Principala diferență față de Custom URL Scheme: Universal Link nu necesită înregistrarea unei scheme personalizate (myapp://) — se folosește un domeniu obișnuit. Aceasta elimină problema URL Scheme hijacking, când orice aplicație poate înregistra aceeași schemă.
Apple a prezentat Universal Link la WWDC 2015 în cadrul iOS 9. Mecanismul a devenit parte a ecosistemului Handoff și Spotlight: Universal Link funcționează nu doar în browser, ci și în rezultatele căutării Spotlight, în Mail, Messages și alte aplicații sistem. În plus, Universal Link este suportat în watchOS și macOS — utilizatorul poate deschide aplicația pe iPhone printr-un link pe Mac.
Avantajul cheie: URL unic. Dezvoltatorul nu gestionează două linkuri diferite (unul pentru web, altul pentru aplicație). Universal Link este același link https. Dacă aplicația este instalată — se deschide ea. Dacă nu — același link se deschide în Safari ca o pagină web obișnuită. Aceasta oferă un fallback ideal fără pierdere de trafic.
Mecanismul Universal Link constă din trei etape: verificarea asocierii, procesarea linkului și fallback în browser. Fiecare etapă este critică pentru funcționarea corectă. Dacă asocierea nu este configurată, iOS tratează linkul ca pe o tranziție obișnuită în Safari. Să examinăm fiecare etapă în detaliu.
La prima accesare a linkului, iOS descarcă fișierul apple-app-site-association de pe server la adresa https://example.com/.well-known/apple-app-site-association. Fișierul conține JSON cu identificatorul Team ID și Bundle ID al aplicației, precum și lista de căi pe care aplicația trebuie să le deschidă. iOS memorează în cache acest fișier și verifică periodic actualitatea lui (la actualizarea aplicației, repornirea dispozitivului).
Fișierul JSON apple-app-site-association trebuie să fie accesibil prin HTTPS fără redirecționări. Serverul trebuie să returneze Content-Type: application/json. Important: fișierul nu are extensia .json — iOS îl caută strict la calea /.well-known/apple-app-site-association. Apple recomandă, de asemenea, adăugarea suportului pentru Universal Link în CDN și verificarea că fișierul nu este blocat de robots.txt.
// apple-app-site-association — configurație minimă
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TEAMID.com.example.app",
"paths": ["/product/*", "/profile/*", "/search"]
}
]
}
}
appID se formează ca Team ID + Bundle ID (TEAMID.com.example.app). paths — un array de șabloane URL pe care aplicația trebuie să le proceseze. Se pot folosi *, ? și notația NOT: ["NOT /admin/*", "/product/*"]. Căile sunt verificate în ordinea enumerării: prima potrivire determină comportamentul. Dacă calea nu se potrivește — linkul se deschide în Safari.
După verificarea reușită a asocierii, iOS transmite linkul aplicației. Procesarea se face în AppDelegate prin metoda application(_:continue:restorationHandler:) pentru NSUserActivity sau în SceneDelegate prin scene(_:continue:). Dezvoltatorul primește un obiect NSUserActivity de tipul NSUserActivityTypeBrowsingWeb, extrage URL-ul și navighează la ecranul corespunzător.
// Procesarea Universal Link în AppDelegate
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping UIUserActivityRestorationHandler
) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL
else { return false }
// Navigare la ecran conform URL
DeepLinkRouter.navigate(to: url)
return true
}
DeepLinkRouter în exemplul de mai sus este o clasă personalizată care parsează URL-ul și apelează coordonatorul de navigare corespunzător. Pentru SwiftUI, procesarea se face prin metoda onOpenURL sau modificatorul environment(\.openURL). Este important să se proceseze nu doar pornirea în prim-plan (foreground), ci și cazul când aplicația nu este pornită (cold start): Universal Link în acest caz deschide aplicația prin opțiunile de lansare.
Dacă aplicația nu este instalată, iOS deschide automat Universal Link în Safari. Aceasta este diferența cheie față de Custom URL Scheme: utilizatorul nu vede o eroare. Fallback este o pagină web standard a aceluiași domeniu. Dezvoltatorul poate plasa pe această pagină un link către App Store, informații despre produs sau conținut alternativ.
Important: fallback nu poate fi personalizat la nivel de iOS. iOS deschide pur și simplu URL-ul în Safari. Pentru a afișa conținut diferit utilizatorilor cu aplicația instalată și neinstalată, utilizați Smart App Banner (meta-tag pentru Safari care sugerează deschiderea aplicației) sau detectarea instalării aplicației prin JavaScript. Apple oferă, de asemenea, SKAdNetwork pentru atribuirea instalărilor prin Universal Link.
Universal Link și Deep Link tradițional (Custom URL Scheme) rezolvă aceeași problemă, dar diferă fundamental prin arhitectură și securitate. Custom URL Scheme — un protocol personalizat (myapp://) care se înregistrează în Info.plist. Orice aplicație poate înregistra aceeași schemă (myapp://), iar iOS nu poate determina care dintre ele este „adevărată". Aceasta se numește URL Scheme hijacking.
Universal Link rezolvă problema hijacking-ului prin verificarea domeniului. Doar proprietarul domeniului poate plasa apple-app-site-association pe serverul său, confirmând legătura cu un anumit Bundle ID. Două aplicații nu pot înregistra același Universal Link: dacă apare un conflict, iOS acordă prioritate aplicației instalate ultima sau deschide Safari.
O altă diferență: Fallback. Custom URL Scheme nu are fallback — dacă aplicația nu este instalată, browserul afișează o eroare. Universal Link deschide site-ul. URL unic înseamnă că valoarea SEO a linkului se păstrează (linkul este indexat de Google), iar utilizatorul cu orice dispozitiv primește conținut relevant. Universal Link este un pas evolutiv de la deep link la unified link.
| Caracteristică | Custom URL Scheme | Universal Link |
|---|---|---|
| Format | myapp://path | https://domain/path |
| Verificare | Nu | apple-app-site-association |
| Securitate | Vulnerabil la hijacking | Doar proprietarul domeniului |
| Fallback | Eroare | Site în Safari |
| Versiune iOS | iOS 3+ | iOS 9+ |
Configurarea Universal Link include partea de server și partea client. Partea de server — plasarea fișierului apple-app-site-association la adresa https://domain/.well-known/apple-app-site-association. Partea client — înregistrarea domeniului în Associated Domains în Xcode (Capabilities → Associated Domains → applinks:example.com). După aceasta, aplicația primește automat toate Universal Link-urile pentru domeniul specificat.
Pașii de configurare:
Depanarea Universal Link — o durere de cap frecventă pentru dezvoltatorii iOS. Principalele cauze ale linkurilor nefuncționale: fișierul apple-app-site-association inaccesibil prin HTTPS, appID incorect, Content-Type diferit de application/json, redirecționare de pe calea /.well-known, memorarea în cache a unei versiuni vechi (resetare prin Settings → Developer → Associated Domains Development). Apple oferă instrumentul „Validation Checker" în Apple Developer Console pentru testarea asocierii.
Branch și alte platforme MMP simplifică configurarea Universal Link: ele generează apple-app-site-association automat și îl găzduiesc pe propriul domeniu. Dezvoltatorul trebuie doar să adauge domeniul Branch în Associated Domains și să integreze SDK-ul. Acest lucru este deosebit de convenabil pentru startup-urile care nu au propria infrastructură de server pentru găzduirea fișierului AASA.
Universal Link are câteva limitări. Prima: fișierul apple-app-site-association trebuie să fie accesibil strict prin HTTPS (HTTP nu este suportat). A doua: linkul trebuie să ducă la același domeniu care este specificat în Associated Domains. Universal Link-urile între domenii nu funcționează — pentru fiecare domeniu este necesară o înregistrare separată în Capabilities și un fișier AASA separat. A treia: Universal Link nu funcționează în WKWebView — doar în Safari și componentele sistem.
Compatibilitate: iOS 9.0+ (Universal Link), watchOS 6.0+ (Handoff Universal Link), macOS 10.15+ (Catalyst și aplicații Mac). În versiunile mai vechi de iOS, linkul se deschide în Safari. Aceasta înseamnă că pe iOS 8 (mai puțin de 1% din dispozitive) Universal Link nu va funcționa. Se recomandă suportarea și a Custom URL Scheme ca fallback pentru dispozitivele vechi, dacă publicul include utilizatori cu versiuni învechite.
Schimbări iOS 16+: Apple a îmbunătățit procesarea Universal Link pentru SwiftUI. A apărut un nou modificator environment(\.openURL) cu posibilitatea de procesare întârziată. iOS 16 permite, de asemenea, deschiderea Universal Link în aplicație chiar și prin SFSafariViewController. Pentru utilizatorii iOS 16, se recomandă trecerea completă la procesarea Universal Link în SwiftUI, păstrând codul AppDelegate doar pentru compatibilitate inversă.
Întrebări frecvente
Universal Link folosește un HTTPS-URL standard și este verificat printr-un fișier pe server. Custom URL Scheme folosește un protocol personalizat (myapp://) fără verificare, ceea ce îl face vulnerabil la interceptarea de către o altă aplicație care a înregistrat aceeași schemă.
Fișierul se plasează în rădăcina serverului HTTPS la calea /.well-known/apple-app-site-association (fără extensia .json). Serverul trebuie să returneze Content-Type: application/json. Important: fără redirecționări, fișierul trebuie să fie accesibil direct.
Cauze principale: Team ID sau Bundle ID incorect în fișierul AASA, fișier inaccesibil prin HTTPS, redirecționare, Content-Type incorect, memorarea în cache a unei versiuni vechi. Verificați prin Developer → Associated Domains Development și resetați cache-ul prin repornirea dispozitivului.
Nu — Universal Link necesită un server HTTPS pe care este găzduit apple-app-site-association. Fără domeniu, Universal Link nu funcționează. Alternativă: Custom URL Scheme (mai puțin sigur) sau servicii terțe (Branch, Firebase) cu propriul domeniu.
Nu — Universal Link este o tehnologie exclusivă Apple pentru iOS, iPadOS, watchOS și macOS. Pe Android, echivalentul se numește App Link (Android 6.0+), care folosește Digital Asset Links (assetlinks.json) în loc de apple-app-site-association.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și