DEV Community

Cristian Dornelles
Cristian Dornelles

Posted on

Checkpoint da Série: o que já funciona, o que quebrou e para onde vamos (Parte 4.5)

Header

Quatro posts, três plataformas, um bug encontrado em produção.

Antes de seguir para App Links e Universal Links no ar de verdade — com domínio, verificação bidirecional e os problemas que só aparecem fora do emulador — vale um respiro para ver o que já existe e o que ainda falta.


O que construímos até aqui

Post 1 — A fundação conceitual

Tipos de deep link, diferenças entre custom scheme, App Links e Universal Links, e a estrutura base em Dart. Nada de pacote externo — só entender o problema antes de escrever código.

Parte 1 — O Guia para Iniciantes

Post 2 — Android nativo

AndroidManifest.xml com intent-filter para custom scheme e HTTPS. MainActivity.kt registrando os canais nativos — MethodChannel para cold start, EventChannel para app em execução.

Parte 2 — Android com Kotlin

Post 3 — iOS nativo

Info.plist com CFBundleURLTypes, Runner.entitlements com Associated Domains e AppDelegate.swift espelhando a mesma lógica de canais do Android.

Parte 3 — iOS com Swift

Post 4 — Integração Flutter

O DeepLinkService como ponto único de entrada: MethodChannel busca o link inicial, EventChannel recebe links com o app aberto, StreamController.broadcast() distribui para quem estiver ouvindo. A SignupPage pré-preenche o referral code e mostra um indicador visual quando o dado veio de um link.

Parte 4 — Integração Flutter


O bug que encontramos na prática

Durante os testes do Post 4, o app abria normalmente mas o referral code nunca aparecia. Nenhum erro, nenhum log — o deep link simplesmente sumia.

A causa: race condition com StreamController.broadcast().

O problema na prática

// ❌ como estava — evento perdido
await service.initialize(); // link emitido aqui...
_deepLinkSub = service.deepLinkStream.listen(...); // listener registrado tarde demais
Enter fullscreen mode Exit fullscreen mode
// ✅ como ficou — listener primeiro
_deepLinkSub = service.deepLinkStream.listen(...); // ouvindo antes de qualquer evento
await service.initialize(); // link emitido com listener ativo
Enter fullscreen mode Exit fullscreen mode

O broadcast() não bufferiza. Se nenhum listener estiver ativo no momento em que o evento é emitido, ele se perde. A ordem importa.

Esse é o tipo de bug que não aparece em log, não quebra o app, e passa despercebido até produção.


Onde estamos agora

O fluxo ponta a ponta já funciona:

  • Android → captura o intent corretamente
  • iOS → captura a URL corretamente
  • Flutter → recebe via MethodChannel / EventChannel e processa
  • UI → reage ao deep link com o referral code pré-preenchido

Fluxo ponta a ponta

Mas ainda falta o mais difícil: fazer isso funcionar fora do ambiente de desenvolvimento.

Código completo: FitConnect no GitHub — branch post/04-flutter.


Para onde vamos

Post 5 — Produção de verdade

App Links no Android e Universal Links no iOS exigem verificação bidirecional de domínio. Sem isso, o link abre no navegador em vez do app. Vamos configurar o assetlinks.json e o apple-app-site-association, entender o que o sistema verifica e o que fazer quando a verificação falha.

Post 6 — Deferred Deep Links

O usuário clica no link mas não tem o app instalado. Vai para a loja, instala, abre — e o referral code sumiu. O deferred deep link resolve isso. Vamos implementar com LocalStorage no lado web e uma estratégia simples no backend.

Post 7 — Página de redirect inteligente

Uma página HTML que detecta a plataforma, tenta abrir o app, e redireciona para a loja se não conseguir. O elo que conecta o link compartilhado ao app instalado.

Post 8 — Testes e troubleshooting

Checklist de deploy, como testar cada cenário (cold start, app aberto, link inválido), e os erros mais comuns com App Links e Universal Links — incluindo os que só aparecem depois do deploy.

Post 9 — Refatoração com Clean Architecture

O DeepLinkHandler como alternativa ao DeepLinkService atual — separando responsabilidades, facilitando testes e preparando o código para crescer sem virar bagunça.


Se você chegou agora, os quatro primeiros posts constroem a fundação do zero. Se acompanhou desde o início, os próximos cinco levam para produção — com os problemas reais que aparecem quando o domínio precisa estar verificado e o usuário ainda não tem o app.


Código completo disponível no repositório: FitConnect no GitHub


Se esse conteúdo te ajudou, deixa um ❤️ ou um 🔖 aqui no DEV.to — isso ajuda o post a alcançar mais devs.

E você, já implementou deep links no seu app?

Qual foi o maior desafio que encontrou?

Quero usar esses casos reais nos próximos posts da série 👇

Tags: Flutter, Dart, MethodChannel, Deep Links, Mobile Development

Top comments (0)