En la web abierta, speechSynthesis lee texto en voz alta y webkitSpeechRecognition convierte la voz en texto. Dentro de un WebView ambos enmudecen —pero el peligro es que uno finge funcionar.

Android: speechSynthesis simplemente no está

Android WebView nunca implementó el lado de texto a voz de la Web Speech API. speechSynthesis no se proporciona, getVoices() devuelve una lista vacía y el evento voiceschanged nunca se dispara. Está bien documentado: proveedores como ResponsiveVoice señalan que el TTS nativo "no es compatible con Android WebView" y la página debe recurrir a una API de síntesis del lado del servidor. Para una app híbrida con Cordova o Capacitor, la misma brecha aparece por defecto. La página que llama a speechSynthesis.speak() obtiene silencio, no un error del que pueda recuperarse.

iOS: la API está expuesta pero muerta

iOS es el caso más insidioso. En WKWebView, webkitSpeechRecognition está presente en window —así que una comprobación como if (window.webkitSpeechRecognition) pasa— pero nunca funciona realmente. El rastreador de errores de WebKit lo registra con precisión: el aviso de permiso nunca aparece y la llamada devuelve un error service-not-allowed porque la app anfitriona no declaró la descripción de uso del reconocimiento de voz. La página cree que la entrada por voz está disponible, la llama y no obtiene nada. El texto a voz en WKWebView es igualmente poco fiable. La detección de características, en lo que los desarrolladores confían para ramificarse bien, miente activamente aquí.

Qué se rompe cuando la voz muere

  • La lectura accesible desaparece. Los operadores con discapacidad visual que dependen de que la página lea cotizaciones, estados de cuenta o alertas en voz alta quedan en silencio.
  • La confirmación de operación por voz puede no hablar nunca. Un bróker que anuncia "orden colocada" vía TTS puede fallar en silencio al decirlo: una brecha peligrosa cuando el usuario asume que la confirmación ocurrió.
  • La búsqueda y dictado por voz se detienen. La entrada manos libres en un coche o en un taller nunca abre el reconocedor.
  • Silencioso y falsamente "soportado". Especialmente en iOS, la API parece presente, así que la página lanza una UI de voz que nunca funciona.

La solución en el runtime

Un runtime propio del host conecta la capa de voz. La página llama a runtime.speak(text, opts) para leer en voz alta y a runtime.startDictation() para entrada por voz, y el host las resuelve con motores nativos: Android TextToSpeech y SpeechRecognizer, iOS AVSpeechSynthesizer y SFSpeechRecognizer (con las descripciones de uso requeridas declaradas en la app). La capacidad se consulta honestamente, las voces son nativas e instaladas, y el resultado es verificable. Una integración, todos los motores, audio real al final.

DimensiónWebViewRuntime propio del host
speechSynthesis (TTS)Ausente en Android WebView; poco fiable en WKWebViewTextToSpeech / AVSpeechSynthesizer nativos
webkitSpeechRecognitionExpuesto pero muerto en WKWebView (service-not-allowed)SFSpeechRecognizer / SpeechRecognizer nativos
Detección de característicasMiente (API presente, sin aviso)Consulta honesta de capacidad
Voz para accesibilidadBrecha silenciosaLectura fiable
Confirmación de operación por vozPuede no hablar nuncaNativa, verificable
ConsistenciaTrampa por motorUniforme

Una app nativa habla y escucha en todos los dispositivos. Un WebView estándar habla en casi ninguno y, en iOS, miente sobre el resto. Un runtime le da a la página una llamada speak y una llamada dictation —y audio real al final de cada una.

Fuentes