Talently
Talently
Desarrollador Móvil

Desarrollador Móvil

Construye experiencias nativas y multiplataforma que los usuarios llevan en el bolsillo.

Un Mobile Developer diseña e implementa aplicaciones para dispositivos iOS y Android. Puede especializarse en desarrollo nativo (Swift para iOS, Kotlin para Android) o en frameworks multiplataforma como React Native o Flutter. Su trabajo requiere entender las particularidades de cada plataforma, las restricciones de hardware y conectividad, y las guías de diseño propias de cada ecosistema. Colabora estrechamente con diseñadores UX, backend developers y QA para entregar experiencias fluidas, seguras y aprobadas por las tiendas de aplicaciones.

SwiftKotlinReact NativeFlutterXcodeAndroid Studio

Recluta al mejor Desarrollador Móvil aquí

Empieza ahora

Responsabilidades Principales

  • Desarrollar y mantener aplicaciones móviles para iOS y/o Android siguiendo las guías de diseño de cada plataforma (HIG de Apple, Material Design de Google).
  • Integrar APIs REST o GraphQL del backend con manejo robusto de errores, estados de carga y escenarios offline.
  • Optimizar el rendimiento de la aplicación en términos de fluidez de animaciones, tiempo de inicio y consumo de batería y memoria.
  • Gestionar el ciclo de publicación en App Store y Google Play, incluyendo firma de builds, configuración de permisos y cumplimiento de políticas.
  • Implementar mecanismos de almacenamiento local seguro, caché y sincronización de datos para soporte offline.
  • Escribir tests automatizados de UI y lógica de negocio, y colaborar con QA en testing de dispositivos reales.

Habilidades Clave

Technical Skills

  • Desarrollo nativo en Swift (iOS) o Kotlin (Android) con conocimiento profundo del ciclo de vida de la aplicación y sus componentes
  • Frameworks multiplataforma: React Native o Flutter para desarrollo eficiente en ambas plataformas desde una base de código
  • Gestión de estado en mobile: Redux, MobX, Riverpod, o soluciones nativas como SwiftUI's @StateObject y ViewModel de Android
  • Consumo de APIs REST/GraphQL con manejo de conectividad intermitente, reintentos y caché local
  • Almacenamiento local con SQLite, Core Data, Room o Realm según la plataforma y complejidad del modelo de datos
  • Testing en mobile: XCTest/Espresso para tests de UI, Jest para lógica en React Native, y testing en múltiples dispositivos y versiones de OS

Soft Skills

  • Empatía con el usuario móvil: entender contextos de uso en movimiento, interrupciones frecuentes y pantallas pequeñas
  • Atención al detalle en animaciones, transiciones y comportamiento táctil que definen la calidad percibida de la app
  • Comunicación con diseño para cuestionar o adaptar especificaciones que no son técnicamente viables en la plataforma objetivo
  • Criterio para priorizar qué funcionalidades merecen soporte offline frente a la complejidad que añade implementarlo
  • Paciencia y metodología en el proceso de review y publicación en las tiendas, que involucra tiempos y políticas externas
  • Capacidad de mantenerse actualizado en ecosistemas que cambian con cada versión mayor de iOS y Android

Casos de uso reales

Contexto

Las apps de consumo compiten por atención en tiendas con millones de alternativas. La fluidez, el tiempo de inicio y la experiencia de onboarding son factores directos de retención.

Ejemplos reales

  • Apps de delivery con tracking en tiempo real y pagos integrados
  • Aplicaciones de streaming de video y audio con reproducción en background
  • Redes sociales con feeds infinitos, cámara y notificaciones push
  • Apps de fitness con integración a HealthKit y Google Fit

Contexto

Las apps B2B o de uso interno requieren soporte offline robusto, integración con sistemas corporativos y políticas de seguridad estrictas.

Ejemplos reales

  • Apps de inventario y logística con escáner de códigos de barras
  • Herramientas de inspección y auditoría que funcionan sin conexión
  • Apps de fuerza de ventas con sincronización con CRM
  • Gestión de turnos y asistencia con autenticación biométrica

Contexto

Las aplicaciones financieras requieren seguridad adicional en el almacenamiento de datos, la comunicación con el servidor y la verificación de identidad del usuario.

Ejemplos reales

  • Wallets digitales con autenticación biométrica y cifrado local
  • Apps de inversión con cotizaciones en tiempo real
  • Onboarding con verificación de identidad (KYC) y escaneo de documentos
  • Transferencias con OTP y confirmación por push notification

Contexto

Mobile permite acceder a hardware que no existe en web: cámara, GPS, sensores, Bluetooth y NFC. Esto habilita casos de uso únicos de la plataforma.

Ejemplos reales

  • Aplicaciones de AR con ARKit o ARCore para visualización de productos
  • Pagos por NFC y lectura de tarjetas con tap-to-pay
  • Apps de salud con lectura de sensores del wearable via Bluetooth LE
  • Escaneo de documentos y OCR directamente desde la cámara

Contexto

Cuando el equipo es pequeño o el time-to-market es prioritario, los frameworks multiplataforma permiten compartir lógica de negocio y UI entre iOS y Android con un costo de mantenimiento reducido.

Ejemplos reales

  • MVPs móviles lanzados simultáneamente en ambas plataformas
  • Apps corporativas internas donde la experiencia nativa premium no es crítica
  • Productos que comparten lógica de negocio con una web app en el mismo lenguaje
  • Migraciones incrementales de apps nativas a React Native por módulos

Preguntas básicas

Nativo cuando la app requiere acceso profundo a APIs de la plataforma, rendimiento máximo en animaciones o gráficos, o integración con hardware específico. Multiplataforma cuando el equipo es pequeño, el time-to-market es prioritario, o la app no requiere diferenciarse profundamente entre plataformas. El costo de mantenimiento de dos codebases nativas suele justificar multiplataforma para la mayoría de apps de negocio.
Implementar una capa de caché local que sirva datos cuando no hay conexión. Las operaciones de escritura se encolan localmente y se sincronizan al recuperar conectividad. Detectar el estado de red con APIs nativas (Network Framework en iOS, ConnectivityManager en Android) y comunicar el estado al usuario de forma clara sin bloquear la UI innecesariamente.
Modelos de navegación distintos (stack con back button en Android vs gestos y navigation bars en iOS), permisos con flujos diferentes, manejo del teclado virtual, comportamiento de notificaciones, y guías de diseño (Material Design vs HIG). Incluso con multiplataforma, ignorar estas diferencias produce una app que se siente extraña en una de las plataformas.
Usar el almacenamiento seguro provisto por la plataforma: Keychain en iOS y EncryptedSharedPreferences o Keystore en Android. Nunca almacenar credenciales en SharedPreferences sin cifrar, en archivos planos o en el bundle de la app. Para apps con requisitos de seguridad elevados, añadir autenticación biométrica antes de acceder al Keychain.
Reemplazar polling constante por push notifications o WebSockets cuando sea posible. Si el polling es necesario, usar intervalos adaptativos (más frecuentes cuando la app está en primer plano, reducidos en background). Aprovechar las APIs de background fetch de la plataforma que el OS optimiza para eficiencia energética, en lugar de procesos en background propios.
Para bugs en lógica de negocio o UI que no requieren cambios nativos: usar un sistema de actualización OTA como CodePush (React Native) o remote config. Para bugs en código nativo: publicar un hotfix en las tiendas, lo que puede tomar entre horas y días dependiendo de la plataforma. Por esto, los feature flags y la capacidad de desactivar features remotamente son críticos en producción móvil.
Definir una política de versiones mínimas soportadas basada en los datos de uso del producto (o datos del mercado si es app nueva). Usar las APIs más estables y evitar APIs marcadas como deprecated. Ejecutar tests en una matriz de dispositivos reales o en servicios como Firebase Test Lab o AWS Device Farm. Implementar crash reporting (Crashlytics, Sentry) desde el día uno para detectar problemas en producción.
Eventos clave de navegación, errores con stack trace completo, contexto del usuario (sin PII), versión de la app, versión del OS y modelo de dispositivo. Usar niveles de log diferenciados (debug, info, warning, error) y asegurarse de que los logs de debug no lleguen a producción. Integrar un servicio de crash reporting que capture el estado de la app en el momento del error.

Preguntas técnicas

iOS tiene estados: Not Running, Inactive, Active, Background y Suspended. En Background, la app tiene tiempo limitado para completar tareas antes de ser suspendida. Para tareas más largas existen APIs específicas: BGTaskScheduler para procesamiento diferido, URLSession background para descargas. El sistema puede terminar apps en background bajo presión de memoria. La app debe guardar estado en applicationWillResignActive y restaurarlo en applicationDidBecomeActive.
Usar Instruments (iOS) o Systrace/Perfetto (Android) para identificar qué trabajo ocurre en el hilo principal durante el scroll. Causas frecuentes: decodificación de imágenes en el hilo principal, cálculo de layouts síncronos, o acceso a base de datos en UI thread. Soluciones: pre-calcular layouts, usar AsyncImage o librerías de carga de imágenes con caché, mover operaciones pesadas a background queues, e implementar cell reuse correctamente.
Ambos permiten escribir código asíncrono con sintaxis secuencial evitando callback hell. Swift async/await se integra con el actor model para thread safety. Kotlin coroutines tienen CoroutineScope y Dispatchers para controlar el contexto de ejecución. En ambos, el principio es el mismo: suspender la ejecución sin bloquear el hilo, continuando cuando el resultado está disponible. La elección depende de la plataforma; en multiplataforma con KMM, Kotlin coroutines son la opción natural.
Universal Links (iOS) y App Links (Android) permiten que URLs del dominio abran la app si está instalada, y el navegador si no lo está. Requieren configurar un archivo JSON en el servidor (apple-app-site-association o assetlinks.json) y registrar los dominios en la app. El sistema operativo verifica la asociación al instalar la app. El manejo del link ocurre en el AppDelegate/SceneDelegate (iOS) o en el intent de la Activity (Android), parseando la URL y navegando al contenido correcto.
Diferir inicializaciones no esenciales a después del primer frame visible. Reducir el trabajo en el hilo principal durante el launch. Minimizar el número de frameworks cargados al inicio con lazy linking. En iOS, usar instruments con el template 'App Launch'. En Android, usar el perfil de inicio y la compilación AOT. Mostrar un Launch Screen estático mientras se carga en lugar de una pantalla en blanco.
Asociar todos los datos a un identificador de usuario en el servidor, no al dispositivo. Implementar un mecanismo de sync basado en timestamps o vectores de versión para detectar conflictos. El servidor es la fuente de verdad; los cambios locales se envían al servidor y los cambios del servidor se aplican localmente. Para apps con requisitos de sincronización complejos, evaluar soluciones como CloudKit, Firebase Firestore o una implementación CRDT.
Registrar el dispositivo con APNs (iOS) o FCM (Android) y enviar el token al servidor. El servidor usa APNs o FCM para enviar notificaciones. Manejar los casos: app en primer plano (mostrar in-app banner), app en background (notificación del sistema), app cerrada (abrir en contexto correcto al pulsar la notificación). Solicitar permisos en el momento adecuado con contexto claro de por qué se necesitan.
Almacenamiento inseguro de datos sensibles (usar Keychain/Keystore). Comunicación sin certificate pinning susceptible a MITM en redes comprometidas. Ingeniería inversa del binario exponiendo claves o lógica sensible (ofuscación, no hardcodear secretos). Exceso de permisos solicitados que genera desconfianza. Logging de datos sensibles en producción. Seguir las guías OWASP Mobile Top 10 como checklist de seguridad.

Preguntas avanzadas

Implementar una base de datos local como fuente de verdad del cliente (SQLite con Room o Core Data). Las operaciones de escritura se aplican localmente primero y se encolan para sync. Al sincronizar, aplicar una estrategia de resolución de conflictos definida por el negocio. El servidor debe exponer un endpoint de sync que acepte un conjunto de cambios locales y devuelva los cambios del servidor desde un checkpoint. Modelar los datos con timestamps de modificación y soft deletes para facilitar el merge.
Usar el patrón de integración incremental: React Native puede convivir con código nativo en la misma app. Identificar las pantallas de menor complejidad nativa para migrar primero. Mantener la navegación principal en nativo y montar vistas React Native en puntos de entrada controlados. Medir el impacto en tamaño del bundle y rendimiento en cada fase. No intentar migrar todo a la vez; priorizar según el valor de negocio de cada módulo.
Registro inmutable de todas las operaciones con timestamp y contexto del usuario. Cifrado de datos sensibles en reposo y en tránsito. Autenticación robusta con soporte de biometría y MFA. Certificate pinning para prevenir MITM. Manejo de sesiones con timeout automático. Los datos financieros nunca deben aparecer en logs ni en backups no cifrados. La arquitectura debe facilitar auditorías externals: separar claramente la capa de datos del negocio de la presentación.
Pirámide de testing: unit tests de lógica de negocio y ViewModels, tests de integración de componentes con mocks de servicios externos, y una suite acotada de tests de UI con XCUITest o Espresso. Ejecutar la suite en Firebase Test Lab o BrowserStack contra una matriz de dispositivos y versiones prioritarios. Complementar con tests de snapshot para detectar regresiones visuales. El objetivo no es cobertura de líneas sino confianza en los flujos críticos del usuario.
Implementar deduplicación de requests en el cliente: evitar múltiples calls paralelos para el mismo recurso con un mecanismo de request coalescing. Usar caché agresivo con estrategia stale-while-revalidate para reducir requests al servidor. Implementar exponential backoff con jitter en reintentos para evitar thundering herd cuando el servidor se recupera de un incidente. En el servidor, rate limiting por usuario y circuit breakers para proteger los servicios de backend.
Automatizar builds y signing con Fastlane o GitHub Actions. Usar schemes y flavors para separar entornos (dev, staging, prod) sin modificar código. Implementar distribución interna con TestFlight y Firebase App Distribution para QA. Versionar con semantic versioning y automatizar el bump de versión en el pipeline. Para releases de producción, implementar staged rollouts para detectar problemas antes de llegar al 100% de usuarios. Mantener un runbook de rollback documentado.

Errores comunes en entrevistas

Decir 'uso React Native y funciona igual en iOS y Android' demuestra inexperiencia. Un mobile developer sólido conoce las diferencias en UX, comportamiento del sistema operativo y acceso a APIs nativas, y puede explicar qué partes de su solución multiplataforma requieren código específico por plataforma.
Proponer implementaciones que hacen trabajo pesado en el hilo principal, cargan imágenes sin caché o renderizan listas sin virtualización muestra falta de experiencia con las restricciones reales del hardware móvil. Los entrevistadores de empresas con apps de alto tráfico preguntan específicamente por estos escenarios.
La App Store review puede tomar días y rechazar una release por razones no técnicas. No haber considerado esto en la planificación de hotfixes, ni haber trabajado con CodePush o feature flags para mitigar la rigidez del proceso de publicación, es una señal de experiencia limitada en mobile real.
Proponer guardar tokens en AsyncStorage sin cifrar en React Native, o en SharedPreferences en Android, es un error grave que aparece frecuentemente. Un mobile developer debe conocer las APIs seguras de cada plataforma y por qué el almacenamiento por defecto no es suficiente para datos sensibles.
Mobile no es simplemente un frontend más pequeño. Proponer features sin considerar el consumo de batería, el uso de datos móviles, la experiencia en pantallas pequeñas o los patrones de uso intermitente demuestra que el candidato piensa en mobile como si fuera una app de escritorio.
Defender React Native o Flutter para todos los casos sin poder articular sus limitaciones reales (acceso a APIs nativas nuevas, rendimiento en heavy compute, size del bundle) es tan problemático como rechazarlos siempre. Los entrevistadores evalúan si el candidato puede hacer esa elección con criterio técnico y de negocio.