En la web abierta, al tocar un Universal Link el sistema operativo tiene la oportunidad de abrir tu app; un App Link en Android hace lo mismo. Dentro de un WebView, ese traspaso muere. Cuando un WebView carga una URL por sí mismo, el sistema operativo nunca pregunta qué app debe manejarla, por lo que los archivos de asociación que publicaste (apple-app-site-association / assetlinks.json) nunca se consultan. Para una app fintech, eso significa que la redirección que debería llevar al usuario a la app del banco para la autenticación fuerte 3DS/SCA, o a una wallet para confirmar un pago, aterriza en silencio en una página web — o a ninguna. Un runtime propiedad del host puentea la apertura nativa para que el traspaso funcione en todos los motores.

Los Universal Links nunca se disparan dentro de un WebView

Los Universal Links y los App Links de Android son un mecanismo a nivel del sistema. Cuando un usuario toca un enlace en Safari, Chrome o el navegador del sistema, iOS o Android comprueban el archivo de asociación del dominio y, si hay una app instalada que coincida, la abren. La intercepción ocurre antes de que cualquier navegador renderice la página. Pero cuando un WebView carga esa misma URL, la app host ya tiene una vista web abierta y simplemente la renderiza dentro de ella. El sistema nunca se consulta, el archivo de asociación es irrelevante y la app nunca se lanza. Apple lo documenta directamente: instanciar un WKWebView para manejar un Universal Link hace que iOS abra el sitio web en Safari en lugar de tu app; el enlace solo abre la app si el usuario lo toca desde una vista ya embebida — y aun así el host debe actuar. Las redirecciones por JavaScript (window.location.href) no cuentan como navegación iniciada por el usuario, así que el resolvedor del sistema también las ignora.

Los esquemas URI personalizados también se suprimen

La salida antigua — un esquema URI personalizado como myapp:// — tampoco es fiable dentro del WebView. En iOS no existe una forma soportada para que una página dentro de un WKWebView fuerce al host a ceder el control; un esquema personalizado se suprime en la mayoría de los contextos de webview y falla en silencio sin red de respaldo. En Android, un WebView puro tampoco resuelve App Links; solo las Android Custom Tabs (una instancia de navegador real) lo hacen. Un host puede sobreescribir shouldOverrideUrlLoading en Android o implementar decidePolicyFor navigationAction en iOS para llamar a UIApplication.open, pero la mayoría de las apps —especialmente las redes sociales y las super-apps que envuelven contenido de terceros— no lo hacen, porque mantener al usuario dentro de la vista web es el punto. El resultado es el mismo en todas partes: el salto entre apps del que depende la página no ocurre.

Qué se rompe cuando muere el traspaso

  • La redirección 3DS/SCA a la app del banco falla. La autenticación fuerte a menudo delega en la app del banco emisor. Dentro de un WebView ese salto se traga, así que la autenticación se atasca o vuelve en silencio a un respaldo web que el banco nunca terminó.
  • La confirmación de wallet y pagos se rompe. Los enlaces "confirma en tu wallet" que deberían enlazar a Google Pay, Apple Pay o un banco simplemente no hacen nada.
  • Los callbacks de vinculación de cuenta y OAuth fallan. Los flujos "abre la app autenticadora/banco para aprobar" aterrizan en una página en blanco o sin salida.
  • Se pierden la atribución y los traspasos de instalación. Los deep links diferidos que deberían sobrevivir una instalación y llevar al usuario a la pantalla correcta se rompen, dañando los embudos de activación.

La solución del runtime

Un runtime propiedad del host es dueño del traspaso entre apps. La página llama a una API uniforme —runtime.openApp(url)— y el host la resuelve mediante el mecanismo nativo de la plataforma: UIApplication.open en iOS (con el Universal Link o un esquema que el host valida) y un Intent / App Link en Android, con respaldo web cuando no hay app instalada. El runtime también puede detectar que está dentro de una vista embebida y mostrar un botón explícito "Abrir en el navegador", en lugar de un enlace que parece no hacer nada. Una integración, todos los motores, un traspaso real al final.

DimensiónWebViewRuntime propiedad del host
Resolución de enlace por el SONunca se consultaEl host llama a apertura nativa
Universal / App LinksSe traganSe respetan vía apertura nativa
Esquema URI personalizadoSuprimido / fallo silenciosoTraspaso validado por el host
Salida en iOSNinguna fiableUIApplication.open
Salida en AndroidSolo Custom TabsIntent / App Link
Traspaso 3DS / walletSe rompeFunciona
Respaldo sin appNingunoRespaldo web explícito

Una app nativa puede abrir otra app en todos los dispositivos. Un WebView puro, en casi ninguno. Un runtime le da a la página una sola llamada — y un traspaso que realmente aterriza.

Fuentes