Addaw, ir a inicio Donar

Lección 7 de 10 · 14 min de lectura · Revisado el 26/10/2026

Apps híbridas, multiplataforma y WebViews: identificar la tecnología y atribuir los fallos

Como viste en el curso de apps móviles accesibles de este nivel, muchas apps no están escritas solo con UIKit, SwiftUI o Compose: usan React Native o Flutter, o son una web dentro de un contenedor nativo. Para quien evalúa, esto cambia tres cosas: qué referencia aplica a cada parte de la app, qué herramientas pueden ver su árbol de accesibilidad y a quién va dirigida la corrección. Esta lección te enseña a identificar la tecnología, a evaluarla con las herramientas adecuadas y a atribuir cada fallo a quien puede corregirlo.

Identificar la tecnología

La forma más fiable es preguntar al equipo, y debería estar en el plan de evaluación. Cuando no hay respuesta o quieres confirmarla, tienes varias pistas:

  • La pantalla de licencias (en «Acerca de» o en los ajustes) suele listar las librerías de código abierto: Flutter, React Native, Capacitor o Cordova aparecen ahí con frecuencia.
  • Mostrar límites de diseño (Android, Opciones de desarrollador): en una app nativa o en React Native verás un rectángulo por cada vista; en Flutter o en una WebView verás una única superficie grande, porque el contenido se dibuja dentro de ella.
  • El paquete de la app: si el cliente te facilita el APK, el analizador de APK de Android Studio muestra su contenido. Una librería libflutter.so delata Flutter; librerías de React Native o del motor Hermes delatan React Native; una carpeta de recursos con un index.html y ficheros JavaScript delata Cordova o Capacitor.
  • El comportamiento: texto que se selecciona como en un navegador, desplazamientos con rebote propio de la web o un lector de pantalla que anuncia «enlace» o «región» en una app son indicios de contenido web.

Qué referencia aplica a cada capa

Una misma app puede mezclar capas. Evalúa cada una con la referencia que le corresponde y deja claro en cada hallazgo de qué capa se trata:

CapaEjemplosReferenciaHerramientas
NativaUIKit, SwiftUI, Android Views, Jetpack ComposeEN 301 549 (PDF, se abre en una ventana nueva) cap. 11Accessibility Inspector, Accessibility Scanner, Layout Inspector
Multiplataforma con componentes nativosReact Native, .NET MAUICap. 11 (se generan vistas nativas)Las nativas, más el inspector de elementos y las pruebas del framework
Multiplataforma con motor de dibujo propioFlutterCap. 11Las nativas (ven lo que Flutter expone) y el depurador de semántica de Flutter
Contenido web en una WebViewIonic con Capacitor, Cordova, pantallas web incrustadas en una app nativaContenido web: criterios WCAG (la EN remite el contenido web al cap. 9); contenedor nativo: cap. 11Inspección remota del navegador y herramientas de web
Documentos que se abren en la appJustificantes y formularios PDFCap. 10 y PDF/UALas del curso de PDF accesible de este nivel

Como la numeración de los criterios es paralela (11.1.4.3 y 9.1.4.3 son 1.4.3 Contraste (mínimo)), el hallazgo se puede registrar con la referencia de su capa y una nota en la metodología del informe que explique la composición de la app.

Herramientas para cada tecnología

WebViews

El contenido de una WebView se inspecciona como una web, pero en remoto. En Android, conecta el dispositivo por USB y abre chrome://inspect en Chrome de escritorio; la app debe tener activada la depuración de WebView (WebView.setWebContentsDebuggingEnabled(true)), algo habitual en compilaciones de depuración. En iOS, se usa el menú Desarrollo de Safari en un Mac; desde iOS 16.4 la app debe marcar su WKWebView como inspeccionable (isInspectable = true). Con eso tienes las herramientas de desarrollo, el panel de accesibilidad y la posibilidad de ejecutar comprobaciones automáticas como las del nivel 4. Pide estas compilaciones en el plan: sin ellas, solo podrás evaluar la WebView desde fuera, con el lector de pantalla.

Flutter

Flutter dibuja sus propios píxeles y construye un árbol de semántica que traslada a la API de accesibilidad de cada plataforma. Por eso VoiceOver, TalkBack, el Inspector y Scanner solo ven lo que ese árbol contiene. Para inspeccionarlo, pide una compilación de depuración con showSemanticsDebugger: true en MaterialApp, que superpone en pantalla los nodos de semántica con su etiqueta. El equipo puede además automatizar comprobaciones en sus pruebas de widgets:

testWidgets('La pantalla de cita cumple las pautas', (tester) async {
  final handle = tester.ensureSemantics();
  await tester.pumpWidget(const AppCitas());
  await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
  await expectLater(tester, meetsGuideline(iOSTapTargetGuideline));
  await expectLater(tester, meetsGuideline(labeledTapTargetGuideline));
  await expectLater(tester, meetsGuideline(textContrastGuideline));
  handle.dispose();
});

Fallos típicos: zonas táctiles hechas con GestureDetector sin Semantics (no se anuncian como botón o no tienen nombre), gráficos dibujados con CustomPaint sin descripción, listas cuyas filas se leen fragmentadas por falta de MergeSemantics y contenido informativo ocultado por error con ExcludeSemantics.

React Native

React Native genera vistas nativas, así que las herramientas de la plataforma funcionan directamente. El menú de desarrollo incluye un inspector de elementos que relaciona cada vista con su componente. Los fallos más habituales son componentes pulsables (Pressable, TouchableOpacity) sin accessibilityRole="button", que se anuncian sin rol; contenedores pulsables que fusionan todo su contenido en una etiqueta interminable; y modales propios que no impiden al lector salir del diálogo. Para las pruebas, React Native Testing Library permite buscar por rol y nombre, igual que en web: getByRole('button', { name: 'Enviar' }).

Fallos de frontera entre capas

Los problemas más difíciles aparecen donde se tocan dos capas:

  • Paso de nativo a web: al abrir una pantalla web, el foco del lector se queda en la barra nativa o salta al final; no se anuncia ningún título; el botón Atrás nativo y el historial de la web no coinciden.
  • Tamaño de texto: el contenido web no siempre sigue el tamaño de texto del sistema. En iOS, por ejemplo, la web debe usar las fuentes de sistema de WebKit (como font: -apple-system-body) o la app debe ajustar el zoom. Compruébalo siempre con el texto al 200 %.
  • Zoom bloqueado: una etiqueta viewport con user-scalable=no o maximum-scale=1 en el contenido web impide ampliar.
  • Gestos en conflicto: carruseles web que capturan los deslizamientos del lector de pantalla y dejan a la persona atrapada.
  • Contenido duplicado: un texto que existe en la capa nativa y en la web y se lee dos veces.

Error frecuente

Pasar Accessibility Scanner a una app hecha con Capacitor, no obtener avisos y concluir que está bien. Scanner analiza lo que ve el servicio de accesibilidad; en una WebView, muchos problemas web (encabezados que no son encabezados, campos sin etiqueta asociada, orden del DOM) no generan avisos. El contenido web se evalúa con inspección remota y con las pruebas manuales de web que ya conoces.

Atribuir el fallo: app, framework, plataforma o tecnología de apoyo

Un hallazgo bien atribuido se corrige antes. Antes de redactarlo, recorre esta secuencia:

  1. ¿Se reproduce en otro dispositivo, otra versión del sistema y la otra plataforma? Si solo falla con la versión de TalkBack de un fabricante, es probable que no sea un fallo de la app.
  2. ¿Ocurre también con un componente estándar de la plataforma? Si un interruptor del sistema se comporta igual de mal, el problema es de la plataforma o de la tecnología de apoyo.
  3. ¿Es un componente del framework sin modificar? Consulta su documentación y su registro público de incidencias: puede ser una limitación conocida con solución alternativa.
  4. Clasifica y redacta: fallo de la app (lo corrige el equipo), limitación del framework (solución alternativa recomendada y aviso al proyecto), o problema de la plataforma o de la tecnología de apoyo (observación, no incumplimiento de la app, salvo que la app pueda evitarlo con un diseño distinto).

Ejemplo

App bancaria hecha con React Native. En la pantalla de transferencias, VoiceOver y TalkBack leen un único bloque, «1.250,00 euros, Cuenta nómina, termina en 4821, Transferir», sin indicar en ningún momento que se puede pulsar: el contenedor pulsable incluye el resumen de la operación y no declara rol. Se reproduce igual en las dos plataformas y en todos los dispositivos: fallo de la app, no del lector. Hallazgo: 11.4.1.2 Nombre, función, valor (falta el rol). Recomendación: separar el resumen, que queda como texto, del botón, y darle a este accessibilityRole="button" con la etiqueta «Transferir».

Punto clave

La tecnología de la app no cambia lo que se exige, sino cómo lo compruebas y cómo redactas la recomendación. «Añadir etiqueta al botón» no ayuda a un equipo Flutter; «envolver el GestureDetector en Semantics(button: true, label: 'Cerrar')» sí.

Resumen

  • Identifica la tecnología preguntando al equipo y confirmando con licencias, límites de diseño, el paquete de la app o su comportamiento.
  • Cada capa tiene su referencia: cap. 11 para lo nativo y multiplataforma, criterios WCAG de contenido web para lo que carga una WebView, cap. 10 y PDF/UA para los documentos.
  • Las WebViews se inspeccionan en remoto (chrome://inspect, Safari); Flutter con su depurador de semántica y sus pautas en pruebas; React Native con las herramientas nativas y su inspector.
  • Las fronteras entre capas concentran fallos de foco, título, tamaño de texto, zoom y gestos.
  • Atribuye cada fallo (app, framework, plataforma o tecnología de apoyo) antes de redactarlo y escribe la recomendación en el lenguaje del equipo.

Comprueba lo que has aprendido

Esta lección se puede leer libremente. Para hacer su test de 3 preguntas, los ejercicios prácticos con páginas reales, guardar tu avance y optar al examen y al certificado, matricúlate en el curso.

Matricularme · nivel 6 (119 €)