Universal Link é um mecanismo da Apple (iOS 9+) que permite abrir links web diretamente no aplicativo, ignorando o Safari. Se o aplicativo não estiver instalado, o link abre perfeitamente no navegador. O termo foi introduzido pela Apple em 2015 na WWDC como parte do Handoff e do ecossistema Continuity. De acordo com o Apple Developer, o Universal Link proporciona uma experiência de usuário unificada entre a web e o aplicativo nativo sem diálogos de escolha.
Principais pontos
Universal Link é um link HTTPS padrão como https://example.com/page que, ao ser tocado em um dispositivo iOS, abre o aplicativo instalado em vez do Safari. A principal diferença do Custom URL Scheme: o Universal Link não requer o registro de um esquema personalizado (myapp://) — ele usa um domínio normal. Isso elimina o problema de URL Scheme hijacking, onde qualquer aplicativo pode registrar o mesmo esquema.
A Apple apresentou o Universal Link na WWDC 2015 como parte do iOS 9. O mecanismo tornou-se parte do ecossistema Handoff e Spotlight: o Universal Link funciona não apenas no navegador, mas também nos resultados de busca do Spotlight, Mail, Messages e outros aplicativos do sistema. Além disso, o Universal Link é suportado no watchOS e macOS — o usuário pode abrir um aplicativo no iPhone através de um link no Mac.
A principal vantagem: URL única. O desenvolvedor não gerencia dois links diferentes (um para a web e outro para o aplicativo). O Universal Link é o mesmo link https. Se o aplicativo estiver instalado — abre o aplicativo. Se não — o mesmo link abre no Safari como uma página web normal. Isso proporciona um fallback ideal sem perda de tráfego.
O mecanismo do Universal Link consiste em três etapas: verificação de associação, manipulação do link e fallback para o navegador. Cada etapa é crítica para o funcionamento correto. Se a associação não estiver configurada, o iOS processa o link como um redirecionamento normal para o Safari. Vamos examinar cada etapa em detalhes.
No primeiro toque em um link, o iOS baixa o arquivo apple-app-site-association do servidor em https://example.com/.well-known/apple-app-site-association. O arquivo contém JSON com o Team ID e Bundle ID do aplicativo, bem como uma lista de caminhos que o aplicativo deve abrir. O iOS armazena este arquivo em cache e verifica periodicamente sua atualidade (na atualização do aplicativo, reinicialização do dispositivo).
O arquivo JSON apple-app-site-association deve estar acessível via HTTPS sem redirecionamentos. O servidor deve retornar Content-Type: application/json. É importante que o arquivo não tenha extensão .json — o iOS o procura estritamente em /.well-known/apple-app-site-association. A Apple também recomenda adicionar suporte para Universal Link no CDN e verificar se o arquivo não está bloqueado pelo robots.txt.
// apple-app-site-association — configuração mínima
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TEAMID.com.example.app",
"paths": ["/product/*", "/profile/*", "/search"]
}
]
}
}
appID é formado como Team ID + Bundle ID (TEAMID.com.example.app). paths é uma matriz de padrões de URL que o aplicativo deve manipular. Podem ser usados *, ? e a notação NOT: ["NOT /admin/*", "/product/*"]. Os caminhos são verificados na ordem de enumeração: a primeira correspondência determina o comportamento. Se o caminho não corresponder — o link abre no Safari.
Após a verificação bem-sucedida da associação, o iOS passa o link para o aplicativo. A manipulação é feita no AppDelegate através do método application(_:continue:restorationHandler:) para NSUserActivity, ou no SceneDelegate através de scene(_:continue:). O desenvolvedor recebe um objeto NSUserActivity com o tipo NSUserActivityTypeBrowsingWeb, extrai a URL e navega para a tela correspondente.
// Manipulação do Universal Link no AppDelegate
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping UIUserActivityRestorationHandler
) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL
else { return false }
// Navegar para a tela de acordo com a URL
DeepLinkRouter.navigate(to: url)
return true
}
DeepLinkRouter no exemplo acima é uma classe personalizada que analisa a URL e chama o coordenador de navegação correspondente. Para SwiftUI, a manipulação é feita através do método onOpenURL ou do modificador environment(\.openURL). É importante manipular não apenas a inicialização em primeiro plano, mas também o caso em que o aplicativo não estava em execução (cold start): o Universal Link abre o aplicativo através de opções de inicialização neste caso.
Se o aplicativo não estiver instalado, o iOS abre automaticamente o Universal Link no Safari. Esta é uma diferença chave do Custom URL Scheme: o usuário não vê um erro. O fallback é a página web padrão do mesmo domínio. O desenvolvedor pode colocar um link para a App Store, informações do produto ou conteúdo alternativo nesta página.
Importante: o fallback não pode ser personalizado no nível do iOS. O iOS simplesmente abre a URL no Safari. Para mostrar conteúdo diferente para usuários com e sem o aplicativo instalado, use o Smart App Banner (uma metatag para o Safari que oferece abrir o aplicativo) ou detecção de instalação via JavaScript. A Apple também fornece SKAdNetwork para atribuição de instalações através do Universal Link.
O Universal Link e o Deep Link tradicional (Custom URL Scheme) resolvem o mesmo problema, mas diferem fundamentalmente em arquitetura e segurança. Custom URL Scheme é um protocolo personalizado (myapp://) registrado no Info.plist. Qualquer aplicativo pode registrar o mesmo esquema (myapp://), e o iOS não consegue determinar qual é o “verdadeiro”. Isso é chamado de URL Scheme hijacking.
O Universal Link resolve o problema de hijacking através da verificação de domínio. Apenas o proprietário do domínio pode colocar o apple-app-site-association em seu servidor, confirmando a conexão com um Bundle ID específico. Dois aplicativos não podem registrar o mesmo Universal Link: se surgir um conflito, o iOS dá prioridade ao aplicativo instalado mais recentemente ou abre o Safari.
Outra diferença: Fallback. O Custom URL Scheme não tem fallback — se o aplicativo não estiver instalado, o navegador mostra um erro. O Universal Link abre o site. Uma URL única significa que o valor SEO do link é preservado (o Google indexa o link), e um usuário com qualquer dispositivo recebe conteúdo relevante. O Universal Link é um passo evolutivo do deep link para o link unificado.
| Característica | Custom URL Scheme | Universal Link |
|---|---|---|
| Formato | myapp://path | https://domain/path |
| Verificação | Não | apple-app-site-association |
| Segurança | Vulnerável a hijacking | Apenas o proprietário do domínio |
| Fallback | Erro | Site no Safari |
| Versão iOS | iOS 3+ | iOS 9+ |
A configuração do Universal Link inclui a parte do servidor e a do cliente. A do servidor — colocar o arquivo apple-app-site-association em https://domain/.well-known/apple-app-site-association. A do cliente — registrar o domínio em Associated Domains no Xcode (Capabilities → Associated Domains → applinks:example.com). Depois disso, o aplicativo recebe automaticamente todos os Universal Links para o domínio especificado.
Passos de configuração:
A depuração do Universal Link é uma dor de cabeça comum para desenvolvedores iOS. As principais causas de links que não funcionam: arquivo apple-app-site-association não acessível via HTTPS, appID incorreto, Content-Type diferente de application/json, redirecionamento do caminho /.well-known, cache da versão antiga do arquivo (redefinir via Settings → Developer → Associated Domains Development). A Apple fornece a ferramenta Validation Checker no Apple Developer Console para testar a associação.
Branch e outras plataformas MMP simplificam a configuração do Universal Link: eles geram o apple-app-site-association automaticamente e o hospedam em seu próprio domínio. O desenvolvedor só precisa adicionar o domínio do Branch em Associated Domains e integrar o SDK. Isso é especialmente conveniente para startups que não têm sua própria infraestrutura de servidor para hospedar o arquivo AASA.
O Universal Link tem várias limitações. Primeira: o arquivo apple-app-site-association deve estar acessível estritamente via HTTPS (HTTP não é suportado). Segunda: o link deve apontar para o mesmo domínio especificado em Associated Domains. Universal Links entre domínios não funcionam — cada domínio requer uma entrada separada em Capabilities e um arquivo AASA separado. Terceira: o Universal Link não funciona no WKWebView — apenas no Safari e componentes do sistema.
Compatibilidade: iOS 9.0+ (Universal Link), watchOS 6.0+ (Handoff Universal Link), macOS 10.15+ (Catalyst e aplicativos Mac). Em versões mais antigas do iOS, o link abre no Safari. Isso significa que no iOS 8 (menos de 1% dos dispositivos) o Universal Link não funcionará. Recomenda-se também suportar Custom URL Scheme como fallback para dispositivos antigos se seu público incluir usuários com versões desatualizadas.
Mudanças no iOS 16+: a Apple melhorou a manipulação do Universal Link para SwiftUI. Um novo modificador environment(\.openURL) com capacidade de processamento adiado foi introduzido. O iOS 16 também permite abrir Universal Links no aplicativo mesmo através do SFSafariViewController. Para usuários do iOS 16, recomenda-se migrar completamente para a manipulação do Universal Link com SwiftUI, deixando o código do AppDelegate apenas para compatibilidade retroativa.
Perguntas frequentes
Universal Link usa uma URL HTTPS padrão e é verificado através de um arquivo no servidor. Custom URL Scheme usa um protocolo personalizado (myapp://) sem verificação, tornando-o vulnerável à interceptação por outro aplicativo que registrou o mesmo esquema.
O arquivo é colocado na raiz do servidor HTTPS em /.well-known/apple-app-site-association (sem extensão .json). O servidor deve retornar Content-Type: application/json. Importante: sem redirecionamentos, o arquivo deve estar diretamente acessível.
Principais causas: Team ID ou Bundle ID incorretos no arquivo AASA, arquivo não acessível via HTTPS, redirecionamento, Content-Type incorreto, cache da versão antiga. Verifique através de Developer → Associated Domains Development e reinicie o dispositivo para limpar o cache.
Não — o Universal Link requer um servidor HTTPS que hospede o apple-app-site-association. Sem um domínio, o Universal Link não funciona. Alternativas: Custom URL Scheme (menos seguro) ou serviços de terceiros (Branch, Firebase) com seu próprio domínio.
Não — o Universal Link é uma tecnologia exclusiva da Apple para iOS, iPadOS, watchOS e macOS. No Android, o equivalente é chamado de App Link (Android 6.0+), que usa Digital Asset Links (assetlinks.json) em vez de apple-app-site-association.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também