03 — Desarrollo Móvil

iOS, Android, multiplataforma y los backends detrás de ellos

Apps móviles que se entregaron a usuarios reales — y se mantuvieron entregadas — durante más de once años.

iOS y Android nativos en sus propios lenguajes, React Native y Flutter donde encajan, y los backends, cachés y nubes que hacen de un teléfono más que una cáscara delgada. La trayectoria de once años es lo que hace creíble el resto.

Los cimientos

He pasado más de once años construyendo y entregando aplicaciones móviles a usuarios reales — y ese solo hecho es el que hace que cada otra afirmación en esta página merezca ser leída.

Cualquiera puede listar frameworks. La credencial que importa es la longevidad: apps que personas reales instalaron, conservaron y usaron en iOS, Android y Windows, durante más de una década. La trayectoria de once años no es una línea en un currículum — es la evidencia de que las decisiones de abajo se tomaron bajo la presión de software que tenía que seguir funcionando después del lanzamiento.

Trabajo nativo primero. En iOS eso significa Swift y Objective-C con SwiftUI, Core Data, Core Animation y SiriKit; en Android significa Kotlin y Java contra el Android SDK en muchas versiones de SO. Esa fluidez nativa es exactamente lo que hace del trabajo multiplataforma — React Native y Flutter a nivel avanzado, Xamarin a nivel funcional — una elección deliberada en lugar de una forma de evitar una plataforma.

Y una app móvil nunca es solo el cliente. Detrás de ella se sientan backends en Node, Spring Boot, Django, Flask, Rails y Go, exponiendo REST y GraphQL, respaldados por SQLite en el dispositivo y Redis en el servidor, desplegados en Firebase, AWS y Google Cloud. La página que sigue es toda esa superficie, contada como realmente la construyo.

0+

años entregando apps móviles a usuarios reales, en iOS, Android y Windows

0

plataformas nativas mantenidas en sus propios lenguajes — Swift/Objective-C y Kotlin/Java

0

stacks multiplataforma que opero a nivel avanzado — React Native y Flutter

0

frameworks de backend que emparejo con clientes móviles, de Node a Go

Matriz de plataformas

Dos plataformas nativas, dos stacks multiplataforma, una superficie Windows.

La primera decisión en cualquier proyecto móvil es sobre qué construir, y rara vez es la misma respuesta dos veces. La matriz de abajo es cómo lo razono: iOS y Android nativos cada uno en su propio lenguaje, dos stacks multiplataforma que opero a nivel avanzado, y una superficie Windows que mantiene honesta la lógica compartida. El diagrama mapea los lenguajes y frameworks sobre las plataformas en lugar de pretender que una herramienta lo cubre todo.

LENGUAJE OBJETIVO Swift / ObjC Kotlin / Java React Native Flutter iOS Android Windows sólido = fluidez nativa · fino = alcance multiplataforma

Lenguajes y frameworks, mapeados a plataformas

Una matriz, no un monolito — cada plataforma en el lenguaje que recompensa.

iOS recibe Swift y Objective-C; Android recibe Kotlin y Java; Windows recibe su propio cliente. React Native y Flutter abarcan las tiendas cuando la UI no pelea con la plataforma, y la columna de la derecha muestra dónde aterriza realmente cada herramienta.

Leer la matriz es el trabajo: es cómo decido si una función es nativa, multiplataforma o un cliente delgado sobre un backend compartido, antes de escribir una línea de UI.

  • iOS — Swift, Objective-C, SwiftUI, Core Data
  • Android — Kotlin, Java, Android SDK
  • Multiplataforma — React Native, Flutter (avanzado)
  • Windows — cliente de escritorio nativo
iOSAndroidReact NativeFlutterWindows
Por plataforma

Lo que realmente escribo en cada plataforma.

Las plataformas no son intercambiables, y el utillaje lo refleja. Cada pestaña es una plataforma en la que he entregado — los lenguajes, los frameworks y el criterio sobre cuándo cada uno se gana su lugar.

iOS nativo en Swift, con Objective-C donde aún vive

En iOS escribo en Swift y leo Objective-C, porque las bases de código reales que llevan años entregándose rara vez son Swift puro. Construyo interfaces en SwiftUI para pantallas nuevas y mantengo UIKit donde un flujo existente depende de él, en lugar de reescribir código que funciona por el bien de un framework.

La persistencia es Core Data cuando la app posee un grafo de objetos real, y el movimiento es Core Animation cuando una transición necesita sentirse nativa en lugar de aproximada. SiriKit maneja intents de voz donde se ganan su lugar — no en cada pantalla, solo donde un atajo hablado es genuinamente más rápido que tocar.

  • Swift primero, Objective-C leído y mantenido
  • SwiftUI para pantallas nuevas, UIKit conservado donde funciona
  • Core Data para el grafo de objetos, Core Animation para el movimiento
  • Intents de SiriKit donde la voz es de verdad más rápida
iOS, en profundidad

Swift como se lee en una pantalla real.

Un panel de código es más honesto que una lista de funciones — esta es la forma del trabajo en iOS, no una descripción de él.

En iOS me apoyo en SwiftUI para superficies nuevas y Core Data para el grafo de objetos detrás de ellas. El fragmento de abajo es del tipo que escribo a diario: un modelo pequeño y tipado, un fetch que la vista puede observar y un layout que se mantiene declarativo. Es deliberadamente ordinario — el punto de la fluidez nativa es que el código de rutina sea limpio, no ingenioso.

ContactList.swiftSwift · SwiftUI · Core Data
import SwiftUI
import CoreData

struct ContactList: View {
    @FetchRequest(
        sortDescriptors: [SortDescriptor(\.name)]
    ) private var contacts: FetchedResults<Contact>

    var body: some View {
        List(contacts) { contact in
            VStack(alignment: .leading) {
                Text(contact.name)
                    .font(.headline)
                Text(contact.phone)
                    .font(.subheadline)
                    .foregroundStyle(.secondary)
            }
        }
        .animation(.easeInOut, value: contacts.count)
    }
}
SwiftUI · UIKit Core Anim. SiriKit Core Data Swift · Objective-C

El conjunto de frameworks de iOS

SwiftUI arriba, Core Data debajo, SiriKit donde la voz es más rápida.

Los frameworks se componen: SwiftUI renderiza, Core Data persiste, Core Animation maneja el movimiento que SwiftUI no, y SiriKit expone el uno o dos intents donde un atajo hablado de verdad supera al toque. Objective-C sigue en escena porque las apps de larga vida todavía lo contienen, y leerlo es parte de mantenerlas.

Nada de esto se añade por sí mismo. Cada framework está en la app porque un problema específico — persistencia, movimiento, voz — lo pidió.

  • SwiftUI para pantallas nuevas, UIKit conservado donde funciona
  • Core Data para el grafo de objetos
  • Core Animation para el movimiento que se siente nativo
  • Intents de SiriKit solo donde la voz es más rápida
SwiftSwiftUICore DataSiriKit
Android, en profundidad

Kotlin contra el Android SDK, con fragmentación y todo.

Android recompensa la explicitud. El fragmento de abajo es un ViewModel de Kotlin que expone el estado de UI como un flow — consciente del ciclo de vida, sobrevive a cambios de configuración y hace su carga fuera del hilo principal. Habiendo entregado en muchas versiones de SO, escribo código Android que asume la muerte de proceso y los límites de fondo apretados en lugar de esperar evitarlos.

ContactViewModel.ktKotlin · Android SDK
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch

class ContactViewModel(
    private val repo: ContactRepository
) : ViewModel() {
    private val _state =
        MutableStateFlow<UiState>(UiState.Loading)
    val state: StateFlow<UiState> = _state.asStateFlow()

    init {
        viewModelScope.launch {
            runCatching { repo.loadContacts() }
                .onSuccess { _state.value = UiState.Ready(it) }
                .onFailure { _state.value = UiState.Error }
        }
    }
}
VERSIONES DE SO SOPORTADAS mín pico última

Muchas versiones de SO, dispositivos reales

Soporta los teléfonos que los usuarios cargan, no el del keynote.

La fragmentación de Android no es un problema del que quejarse — es el entorno. El trabajo es elegir un SDK mínimo honesto, probar el abanico de versiones y tamaños de pantalla que la base de usuarios real corre, y manejar las reglas de fondo y permisos que se aprietan con cada lanzamiento.

Java sigue en el utillaje junto a Kotlin por la misma razón que Objective-C en iOS: el código entregado vive mucho tiempo, y mantenerlo significa leerlo con fluidez.

  • Kotlin y Java contra el Android SDK
  • Elecciones honestas de SDK mínimo
  • Probado en las versiones que los usuarios corren
  • Manejo explícito de fondo y permisos
KotlinJavaAndroid SDKLifecycle
Arquitectura de la app

La forma de una app, dibujada de la UI al almacén de datos.

Una app móvil es una pila de capas claras — y la disciplina es mantenerlas claras para que cada una pueda probarse y reemplazarse por sí sola.

Sea cual sea la plataforma, la arquitectura a la que recurro es la misma en espíritu: una capa de UI que solo renderiza estado, una capa de dominio que sostiene la lógica, una capa de datos que habla con la red y el almacén del dispositivo, y una frontera de sincronización en medio. El diagrama muestra las capas y la única dirección a la que apuntan las dependencias.

Mantener las flechas apuntando en un solo sentido es lo que hace mantenible la app un año después — la UI no alcanza la red, y la red no sabe de la UI. La misma forma se mantiene tanto si el cliente es Swift, Kotlin, React Native o Flutter.

CAPA UI SwiftUI · Compose · RN · Flutter CAPA DE DOMINIO lógica · reglas · estado CAPA DE DATOS repositorios · ORMs SQLite en dispositivo RED REST · GraphQL

UI → dominio → datos → almacén

Cuatro capas, dependencias apuntando en un solo sentido.

La UI observa el estado y emite intents; la capa de dominio decide; la capa de datos obtiene y persiste; SQLite sostiene la verdad en el dispositivo y la red lleva el resto. Cada frontera es un lugar donde puedo poner un test o intercambiar una implementación sin que las capas de arriba lo noten.

No es arquitectura por sí misma. Es la estructura que dejó que once años de apps siguieran aceptando funciones sin colapsar bajo ellas.

  • La UI renderiza estado, nunca alcanza la red
  • La capa de dominio sostiene la lógica y las reglas
  • La capa de datos posee la red y la persistencia del dispositivo
  • SQLite como fuente de verdad en el dispositivo
ArquitecturaCapasTesteable
Backends

El lado servidor de cada app móvil.

Un cliente móvil es tan bueno como el backend con el que habla — así que construyo ese backend también, en el framework que encaje con el equipo.

Detrás de las apps he entregado Node/Express, Spring Boot, Django, Flask, Ruby on Rails y Go con Gin y Gorm. El framework se elige por el equipo y el presupuesto de latencia, no por costumbre: Node donde el equipo es fluido en JavaScript, Spring donde es una casa JVM, Django o Flask para backends pesados en Python, Rails para CRUD guiado por convención, y Go donde el presupuesto por solicitud es ajustado.

Cada uno expone un contrato — REST o GraphQL — contra el que se construye el cliente móvil, persiste a través de ORMs como Sequelize y Mongoose, y cachea la ruta caliente en Redis. El proceso de abajo es el mismo sin importar qué framework se sienta en medio.

Del contrato a un dispositivo sincronizado

  1. 01 Definir el contrato Esquema REST o GraphQL acordado primero — el cliente y el servidor se construyen contra un contrato, no el uno contra el otro.
  2. 02 Elegir el framework Node/Express, Spring Boot, Django/Flask, Rails o Go (Gin/Gorm) — elegido para encajar con el equipo y el presupuesto de latencia.
  3. 03 Modelar los datos ORMs — Sequelize o Mongoose — sobre el almacén relacional o documental que el dominio realmente necesita.
  4. 04 Cachear la ruta caliente Redis delante de las lecturas costosas, con invalidación explícita en lugar de TTLs esperanzados.
  5. 05 Sincronizar el dispositivo SQLite en el dispositivo, un protocolo de sincronización sobre el contrato, resolución de conflictos definida antes de necesitarla.
  6. 06 Entregar el pipeline Builds firmados, tests automatizados, entrega a tiendas — la CI que convierte un commit en un build que un usuario puede instalar.
handler.goGo · Gin · Gorm
func GetContact(c *gin.Context) {
    id := c.Param("id")
    if cached, err := rdb.Get(ctx, id).Result();
        err == nil {
        c.Data(200, "application/json",
            []byte(cached))
        return
    }
    var contact Contact
    if err := db.First(&contact, id).Error;
        err != nil {
        c.JSON(404, gin.H{"error": "not found"})
        return
    }
    c.JSON(200, contact)
}

Un handler en Go, como se entrega

REST y GraphQL, servidos rápido y tipados.

El fragmento es un handler de Gin que lee a través de Gorm con una caché Redis delante — la forma pequeña y repetible de un endpoint en el que un cliente móvil puede confiar: una respuesta tipada, un error predecible y una caché que quita carga de la base de datos en la ruta caliente.

Sea el framework Go, Node o Spring, el contrato que ve el teléfono es el mismo. Ese es el punto de acordarlo primero.

  • Go con Gin y Gorm en las rutas de presupuesto ajustado
  • Redis cacheando las lecturas costosas
  • Respuestas tipadas, formas de error predecibles
  • Mismo contrato sin importar el framework
GoGinGormRedisREST

El stack móvil completo — del cliente a la nube

Lenguajes iOS
Swift · Objective-C
Frameworks iOS
SwiftUI · UIKit · Core Data · Core Animation · SiriKit
Lenguajes Android
Kotlin · Java
Objetivo Android
Android SDK, muchas versiones de SO
Multiplataforma
React Native · Flutter (avanzado) · Xamarin (funcional)
Escritorio
Clientes de Windows
Backends
Node/Express · Spring Boot · Django/Flask · Rails · Go (Gin/Gorm)
APIs
REST · GraphQL
En dispositivo / datos
SQLite · Redis · Sequelize · Mongoose
Nube móvil
Firebase · AWS · Google Cloud
Oficio de frontend
HTML5 · CSS3 · SASS/SCSS · JS ES6+ · TypeScript
Offline-first

Cuando la red falla — y en un teléfono, lo hará.

Un teléfono se mueve por túneles, ascensores y zonas muertas. Una app que asume conectividad es una app que se cuelga en un spinner frente a un usuario real.

Construyo apps móviles offline-first: el dispositivo escribe en SQLite de inmediato y encola el cambio para sincronizar, de modo que el usuario nunca espera a la red para ver surtir efecto su propia acción. Cuando la conectividad vuelve, la cola se drena sobre el contrato REST o GraphQL, y los conflictos se resuelven por una política decidida por entidad antes de necesitarla.

El diagrama traza ese bucle — escritura local, cola, sincronización, reconciliación — y el modo de fallo es la parte que importa: la app degrada a solo lectura en lugar de perder una escritura en silencio. Esa es la diferencia entre una app en la que los usuarios confían y una que abandonan.

DISPOSITIVO escritura SQLite COLA pendiente SERVIDOR reconciliar ALMACÉN Redis · ORM offline sync (REST/GraphQL) estado resuelto de vuelta

Escritura local → cola → sync → reconciliar

El dispositivo es la fuente de verdad hasta que el servidor está de acuerdo.

Cada escritura aterriza primero en SQLite y se refleja en una cola de sincronización. Una sincronización en segundo plano drena la cola contra el servidor, el servidor reconcilia usando lecturas respaldadas por Redis y el almacén mapeado por ORM, y el estado resuelto fluye de vuelta al dispositivo. El usuario ve feedback local instantáneo y consistencia eventual, no un spinner.

Diseñar la política de conflictos de antemano — last-write-wins, merge o manual — es lo que mantiene honesto el bucle cuando dos dispositivos editan el mismo registro.

  • Escritura local en SQLite antes de cualquier llamada de red
  • Cambio encolado, drenado cuando vuelve la conectividad
  • Política de conflictos definida por entidad por adelantado
  • Degradar a solo lectura, nunca perder una escritura
Offline-firstSQLiteSyncResolución de conflictos

Offline-first — el contrato con la red

Almacén en dispositivo
SQLite — la fuente de verdad mientras está offline
Ruta de escritura
Escritura local primero, encolada para sincronizar
Transporte de sync
REST o GraphQL sobre el contrato acordado
Política de conflictos
Definida por entidad antes de necesitarla
Caché de servidor
Redis delante de las lecturas costosas
Almacén de servidor
Relacional o documental, vía Sequelize o Mongoose
Modo de fallo
Degradar a solo lectura, nunca perder una escritura en silencio

El usuario nunca debería esperar a la red para ver su propia acción. Escribe localmente, sincroniza en segundo plano y nunca pierdas una escritura — esa es toda la disciplina offline-first.

Nube móvil

Firebase, AWS y Google Cloud — elegidas por encaje.

La nube no es una sola decisión. Un equipo pequeño necesita un backend para ayer; un producto que escala necesita control sobre su cómputo. Cada pestaña es una plataforma a la que despliego backends móviles, y el criterio sobre cuándo cada una es la respuesta correcta.

Firebase cuando un equipo pequeño necesita un backend para ayer

Firebase se gana su lugar cuando un producto móvil necesita autenticación, un almacén de datos sincronizado y push sin levantar infraestructura primero. Uso Auth para el inicio de sesión, Firestore para los datos estructurados y consultables, y la Realtime Database donde el patrón de acceso es genuinamente un árbol en vivo en lugar de documentos.

La disciplina es saber dónde Firebase deja de ser la respuesta correcta — reglas de seguridad que tienen que codificar autorización real, y costes de lectura que crecen con un modelo de datos ingenuo. Diseño los documentos en torno a las consultas, no al revés.

  • Auth para el inicio de sesión, Firestore para datos estructurados
  • Realtime Database donde un árbol en vivo encaja con el patrón de acceso
  • Reglas de seguridad tratadas como autorización real
  • Documentos diseñados en torno a las consultas
MÓVIL FIREBASE Auth · Firestore AWS Lambda · EC2 · S3 GCP App Eng · Compute un cliente, el backend que encaja con la carga

Dónde corre realmente el backend

Gestionado donde ahorra trabajo, controlado donde tiene que estarlo.

Firebase Auth y Firestore levantan un backend sincronizado sin infraestructura; Lambda y EC2 dan cómputo serverless y de larga vida en AWS; App Engine y Compute Engine hacen el equivalente en Google Cloud; S3 sostiene los medios que un teléfono descarga. El diagrama mapea el cliente sobre esas opciones.

La restricción móvil corre por todo ello: los arranques en frío se sienten en un teléfono, y las subidas tienen que sobrevivir a un enlace celular. La nube se elige para que la latencia que el usuario ve se mantenga dentro de presupuesto.

  • Firebase — Auth, Firestore, Realtime Database
  • AWS — Lambda, EC2, S3
  • Google Cloud — App Engine, Compute Engine
  • Elegido por encaje operativo, latencia en presupuesto
FirebaseAWSGoogle CloudServerless
Multiplataforma, en profundidad

React Native y Flutter — una elección, no un valor por defecto.

Los stacks multiplataforma dejan que un equipo entregue ambas tiendas desde una sola base de código, y opero React Native y Flutter a nivel avanzado. Pero la razón por la que confío en ellos es que he entregado nativo primero: sé exactamente qué me ahorra el puente y dónde se interpone. Cuando una pantalla necesita Core Animation, un sensor que el puente no expone limpiamente, o un comportamiento de plataforma que la abstracción tapa, bajo a un módulo nativo sin dudar.

Xamarin se sienta a nivel funcional en el utillaje, que es la respuesta correcta en organizaciones inclinadas a .NET donde el resto del stack ya es C#. La decisión entre ellos nunca es sobre lealtad — es sobre ajustar el stack al equipo y al producto, con nativo siempre disponible debajo.

BASE DE CÓDIGO COMPARTIDA React Native · Flutter RENDER iOS RENDER ANDROID módulo Swift módulo Kotlin

Una base de código, dos tiendas, escotilla de escape nativa

Lógica de negocio compartida arriba, módulos nativos donde el puente se detiene.

En una app multiplataforma la lógica de negocio y la mayor parte de la UI viven en una sola base de código compartida — React Native o Flutter — que renderiza tanto a iOS como a Android. Las partes que la abstracción no puede servir bajan a módulos nativos en Swift y Kotlin, de modo que la app nunca cambia capacidad por portabilidad.

Esa escotilla de escape es toda la razón por la que la fluidez nativa importa incluso en un proyecto multiplataforma. La capa compartida cubre el terreno común; los módulos nativos cubren los bordes.

  • Lógica y UI compartidas en una sola base de código
  • Renderiza tanto a iOS como a Android
  • Módulos nativos en Swift / Kotlin en los bordes
  • La capacidad nunca se cambia por portabilidad
React NativeFlutterMódulos nativos
CI para móvil

El pipeline que convierte un commit en una instalación.

La CI móvil es más dura que la CI web — hay dos cadenas de herramientas, firma de código y dos procesos de revisión de tienda entre el commit y el usuario.

Un release móvil no es un deploy; es un build, una firma y un envío. El pipeline que corro hace lint y type-check primero, luego construye el archive de iOS con Xcode y lo firma, construye el APK o AAB de Android firmado con Gradle, y envía artefactos versionados a TestFlight y al canal interno antes de la tienda. La regla es simple: sin pipeline en verde, no hay release.

El diagrama de abajo muestra ese reparto — un commit, dos cadenas de herramientas, dos tiendas — porque el coste de equivocarse en la firma de código o en un bump de versión es un envío rechazado y un día perdido, no un re-deploy rápido.

COMMIT release CHECKS lint · type · test XCODE firma · archive GRADLE AAB firmado App Store Play Store

Commit → comprobaciones → dos builds → dos tiendas

Un commit se reparte en dos builds firmados.

El pipeline corre las comprobaciones estáticas una vez, luego se divide: una ruta Xcode que construye, firma y archiva para iOS, y una ruta Gradle que ensambla y firma para Android. Cada una produce un artefacto versionado que va al canal de pruebas de su tienda antes del release.

Tratar el build firmado como lo único que se entrega — nunca un archive local de la máquina de alguien — es lo que mantiene reproducibles los releases a lo largo de once años de apps.

  • Lint, type-check y tests unitarios como compuerta
  • Xcode firma y archiva para iOS
  • Gradle ensambla APK/AAB firmado para Android
  • Artefactos versionados a canales de prueba, luego tienda
CIFirma de códigoTestFlightGradle

CI móvil — etapa por etapa

Disparador
Commit a una rama de release
Comprobaciones estáticas
Lint, type-check (TypeScript), tests unitarios
Build iOS
Build con Xcode, firma de código, archive
Build Android
Gradle assemble, APK/AAB firmado
Artefacto
Build versionado por plataforma
Entrega
TestFlight / canal interno, luego tienda
Compuerta
Sin pipeline en verde, no hay release
Oficio de frontend

Las superficies web que se sientan junto a la app.

Un producto móvil rara vez es solo la app. Hay páginas de onboarding, superficies de marketing, web views embebidas y lógica compartida que quieren el mismo cuidado que el código nativo. Construyo esas en HTML5 y CSS3 limpios, organizo los estilos con SASS/SCSS para que el sistema de diseño siga siendo un sistema, y escribo la lógica en JavaScript moderno — ES6+ y TypeScript dondequiera que el proyecto tolere un sistema de tipos.

TypeScript en particular se paga solo en móvil: un contrato tipado atrapa el desajuste entre cliente y servidor antes de que un usuario lo vea, y los mismos tipos pueden fluir desde el esquema GraphQL hasta el cliente React Native.

01

HTML5 y CSS3

Las superficies web que se sientan junto a una app móvil — páginas de onboarding, marketing, web views embebidas — construidas en HTML5 y CSS3 limpios en lugar de volcadas en un framework por reflejo.

02

SASS/SCSS

Hojas de estilo organizadas con SASS/SCSS para que el sistema de diseño siga siendo un sistema: variables, partials y mixins en lugar de declaraciones copiadas.

03

JavaScript ES6+

JavaScript moderno para la lógica compartida y la capa web — módulos, async/await y las características del lenguaje que hacen legible una base de código años después.

04

TypeScript

TypeScript dondequiera que el proyecto lo tolere, porque un contrato tipado atrapa el desajuste entre cliente y servidor antes de que un usuario lo vea.

05

APIs REST

REST para los endpoints sencillos con forma de recurso, con versionado y formas de error predecibles en las que el cliente móvil puede confiar.

06

APIs GraphQL

GraphQL donde una pantalla móvil necesita exactamente sus datos en un solo viaje de ida y vuelta — el viaje de red que un teléfono paga es el que vale la pena ahorrar.

El recorrido

Once años, una decisión de plataforma a la vez.

Cimientos, nativo, multiplataforma, backend, nube — el mismo ingeniero, siguiendo el trabajo mientras los productos crecían más allá de sus primeros mil usuarios.

Leído en secuencia, el trabajo móvil es una sola trayectoria continua en lugar de una lista de frameworks. Empieza con once años entregando a usuarios reales, se profundiza en iOS y Android nativos, se extiende por React Native y Flutter donde encajan, alcanza de vuelta los backends que hacen de un cliente más que una cáscara, y llega a las nubes que lo escalan.

Lo que atraviesa todo ello es la misma negativa que recorre el resto de mi trabajo: la app y el sistema detrás de ella son un solo problema, no dos repartidos entre dos personas.

  1. Cimientos Once años entregando a usuarios reales La trayectoria que ancla todo lo demás: más de once años construyendo y entregando apps móviles que personas reales instalaron y usaron, en iOS, Android y Windows.
  2. Nativo iOS y Android en sus propios lenguajes Swift y Objective-C en iOS con SwiftUI, Core Data, Core Animation y SiriKit; Kotlin y Java en Android en muchas versiones de SO. La fluidez nativa que hace informadas las elecciones multiplataforma.
  3. Multiplataforma React Native y Flutter a nivel avanzado Un equipo entregando dos tiendas donde encaja, bajando a módulos nativos donde no — más Xamarin a nivel funcional para equipos inclinados a .NET.
  4. Backend El lado servidor de cada app Node/Express, Spring Boot, Django/Flask, Rails y Go (Gin/Gorm), exponiendo REST y GraphQL, respaldados por SQLite, Redis y ORMs — los backends que hacen de un cliente móvil más que una cáscara delgada.
  5. Nube Firebase, AWS y Google Cloud Almacenes de datos gestionados, cómputo serverless y almacenamiento elegidos por encaje operativo — la infraestructura que escala una app más allá de sus primeros mil usuarios.
Cómo trabajo

Los principios bajo las plataformas.

Las plataformas y frameworks cambian con el producto; los principios no. Estas son las reglas que aplico tanto si la app es Swift nativo, Kotlin nativo, React Native o Flutter — la parte que convirtió once años de trabajo móvil en apps que siguieron funcionando en lugar de un portafolio de lanzamientos.

01

La fluidez nativa gana la abstracción

Porque he entregado Swift y Kotlin directamente, elegir React Native o Flutter es un intercambio medido, no una forma de evitar aprender una plataforma. Sé qué me ahorra el puente y qué me oculta.

02

El contrato va primero

Cliente y servidor se construyen contra un contrato REST o GraphQL acordado, idealmente tipado de principio a fin. La integración se diseña antes de escribir cualquiera de los dos lados, no se negocia después de que ambos se rompan.

03

Asume que la red fallará

Un teléfono se mueve por zonas muertas. La app escribe localmente en SQLite primero, encola para sincronizar y degrada a solo lectura en lugar de perder una escritura o colgarse en un spinner.

04

Respeta las reglas de la plataforma

Límites de fondo, muerte de proceso, revisión de tienda, firma de código — no son obstáculos que rodear. Trabajar con ellos es lo que mantiene una app instalada en lugar de desinstalada.

05

Prueba la fragmentación

Muchas versiones de SO de Android y un abanico de dispositivos iOS significa probar lo que los usuarios realmente cargan, no afirmar que el último lanzamiento cubre a todos.

06

Once años son la credencial

Cada afirmación aquí está respaldada por apps que se entregaron y se mantuvieron entregadas. La longevidad es la evidencia — no un framework en una diapositiva, sino software que sobrevivió al contacto con usuarios reales.

Once años de apps que se entregaron y se mantuvieron entregadas es la credencial. Todo lo demás en esta página es verdad porque esa única cosa lo es.

Open to the right work

Si tu producto es una app móvil y el backend, la nube y el comportamiento offline que la hacen confiable, ese es todo el problema que quiero.

If you are holding a problem that doesn't fit inside one field, that is the conversation I want.

NextCloud & DevOps