Deep links e universal links: abrindo telas específicas de fora do app
Em um ecossistema mobile cada vez mais integrado, a capacidade de direcionar usuários diretamente para conteúdo específico dentro de um aplicativo é um diferencial competitivo crucial. Deep links e universal links são tecnologias que permitem exatamente isso: abrir telas específicas do seu app a partir de fontes externas como e-mails, notificações push, campanhas de marketing ou até mesmo outros aplicativos. Neste artigo, exploraremos os fundamentos, configurações, implementações práticas e boas práticas dessas técnicas, sempre com exemplos de código aplicáveis.
1. Fundamentos dos Deep Links e Universal Links
Deep links são URIs que direcionam o usuário para um conteúdo específico dentro de um aplicativo, em vez de apenas abrir a tela inicial. Eles funcionam como atalhos que transportam o usuário diretamente para a experiência desejada.
Diferença entre deep links tradicionais e universal/App Links:
- Deep links tradicionais (URI schemes): Usam esquemas personalizados como
meuapp://produto/123. São simples de configurar, mas não possuem verificação de domínio, o que pode gerar conflitos se outro app registrar o mesmo esquema. - Universal Links (iOS) e App Links (Android): Usam URLs HTTP/HTTPS padrão (ex:
https://meusite.com/produto/123). A Apple e o Google verificam a propriedade do domínio, garantindo maior segurança e evitando conflitos.
Casos de uso comuns:
- Campanhas de marketing que levam a ofertas específicas
- Notificações push que abrem o item notificado
- Compartilhamento de conteúdo entre usuários
- Redefinição de senha com link direto para a tela de redefinição
2. Configuração de URI Schemes Personalizados
iOS (Info.plist)
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>meuapp</string>
</array>
</dict>
</array>
Android (AndroidManifest.xml)
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="meuapp" android:host="produto" />
</intent-filter>
</activity>
Tratamento de parâmetros dinâmicos:
// Exemplo de link: meuapp://produto/123?ref=email
// No iOS (AppDelegate):
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
let path = url.path // "/produto/123"
let query = url.query // "ref=email"
// Lógica de navegação
return true
}
Limitações: Se outro aplicativo registrar o mesmo esquema meuapp, o sistema operacional pode abrir qualquer um deles, criando uma experiência imprevisível para o usuário.
3. Universal Links no iOS
Para implementar Universal Links, você precisa de:
1. Um servidor HTTPS com o arquivo apple-app-site-association
2. Configuração do domínio associado no Xcode
Arquivo apple-app-site-association (servidor):
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TEAMID.com.seuapp.bundle",
"paths": ["/produto/*", "/categoria/*"]
}
]
}
}
Configuração no Xcode:
- Adicione o domínio em "Associated Domains" com o prefixo applinks:meusite.com
Implementação no AppDelegate:
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL else { return false }
// Extrai o path e navega para a tela correspondente
let path = url.path // "/produto/123"
handleNavigation(path: path)
return true
}
4. App Links no Android
No Android, a configuração envolve Digital Asset Links para verificar a propriedade do domínio.
Arquivo assetlinks.json (servidor):
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.seuapp.package",
"sha256_cert_fingerprints": ["SEU_FINGERPRINT_AQUI"]
}
}]
Intent filter no AndroidManifest.xml:
<activity android:name=".MainActivity">
<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="meusite.com" android:pathPrefix="/produto" />
</intent-filter>
</activity>
Implementação com NavigationComponent:
// No arquivo de navegação (NavHost.kt)
composable(
route = "produto/{id}",
arguments = listOf(navArgument("id") { type = NavType.StringType })
) { backStackEntry ->
val id = backStackEntry.arguments?.getString("id")
ProdutoScreen(id = id)
}
5. Tratamento de Links no React Native
Usando a API Linking nativa do React Native:
import { Linking } from 'react-native';
// Para capturar links quando o app está em primeiro plano
useEffect(() => {
const handleDeepLink = (event) => {
const url = event.url;
// Processa o URL e navega
navigateToScreen(url);
};
Linking.addEventListener('url', handleDeepLink);
return () => {
Linking.removeEventListener('url', handleDeepLink);
};
}, []);
// Para verificar se o app foi aberto por um link
useEffect(() => {
Linking.getInitialURL().then(url => {
if (url) {
navigateToScreen(url);
}
});
}, []);
Com react-navigation e linking config:
const linking = {
prefixes: ['https://meusite.com', 'meuapp://'],
config: {
screens: {
Produto: 'produto/:id',
Categoria: 'categoria/:nome',
},
},
};
// No NavigationContainer
<NavigationContainer linking={linking}>
{/* Suas telas */}
</NavigationContainer>
6. Roteamento e Navegação Após o Recebimento do Link
Mapeamento de parâmetros:
function handleNavigation(url) {
const regex = /https:\/\/meusite\.com\/produto\/(\d+)/;
const match = url.match(regex);
if (match) {
const produtoId = match[1];
navigation.navigate('Produto', { id: produtoId });
}
}
Tratamento de fallback (app não instalado):
// No servidor web, redirecione para a loja:
if (appNaoInstalado) {
window.location.href = 'https://apps.apple.com/br/app/seuapp/id123';
}
Lógica de autenticação: Antes de navegar, verifique se o usuário está logado. Caso contrário, redirecione para a tela de login e, após autenticação, complete a navegação original.
7. Testes e Depuração de Deep Links
iOS (simulador):
xcrun simctl openurl booted "meuapp://produto/123"
xcrun simctl openurl booted "https://meusite.com/produto/123"
Android (emulador ou dispositivo):
adb shell am start -W -a android.intent.action.VIEW -d "meuapp://produto/123" com.seuapp.package
adb shell am start -W -a android.intent.action.VIEW -d "https://meusite.com/produto/123" com.seuapp.package
Validação de assinatura de domínio:
- iOS: Use o site de validação da Apple ou ferramentas como curl -i https://meusite.com/apple-app-site-association
- Android: Use o Digital Asset Links API: https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://meusite.com&relation=delegate_permission/common.handle_all_urls
8. Boas Práticas e Considerações de Segurança
- Validação de origem: Sempre valide a origem do link para evitar ataques de phishing. Nunca confie cegamente em parâmetros recebidos.
- HTTPS obrigatório: Universal Links e App Links exigem HTTPS. Nunca use HTTP para esses fins.
- Cache e fallback: Implemente estratégias para links expirados ou inválidos, como redirecionar para a tela inicial do app ou para uma página de erro amigável.
- Testes em produção: Teste os links em ambientes de staging e produção para garantir que a configuração do servidor está correta.
Deep links e universal links transformam a experiência do usuário, criando um fluxo contínuo entre o mundo web e o aplicativo. Com as técnicas e boas práticas apresentadas, você pode implementar uma navegação eficiente, segura e intuitiva.
Referências
- Apple Universal Links Documentation — Documentação oficial da Apple sobre configuração e implementação de Universal Links no iOS.
- Android App Links Documentation — Guia oficial do Google para implementar App Links no Android com Digital Asset Links.
- React Native Linking API — Documentação oficial da API Linking do React Native para tratamento de deep links.
- React Navigation Deep Linking Guide — Tutorial completo de como configurar deep links com React Navigation, incluindo exemplos práticos.
- Branch.io Deep Linking Best Practices — Guia abrangente sobre melhores práticas de deep linking, incluindo segurança e fallback strategies.