Respuesta corta: sí, Apple permite los live updates, con ciertos límites. Puedes enviar nuevo JavaScript, HTML y CSS a una app de iOS sin pasar por una nueva revisión de la App Store, siempre que la actualización no cambie lo que es la app. No puedes descargar code nativo.
La confusión suele venir de mezclar dos cosas: live updates de code interpretado (permitidos) y la descarga de nuevos code ejecutables (no permitida). Esta página cita las reglas, marca el límite y explica cómo Apple lo hace cumplir.
Esto no es asesoría legal. Es la interpretación actual de las reglas y cómo miles de apps las aplican en producción.
Qué dicen realmente las reglas de Apple
Dos textos son clave. El primero es Directriz de revisión de la App Store 2.5.2:
Las apps deben ser autónomas en sus bundles, y no pueden leer ni escribir datos fuera del área del contenedor designado, ni descargar, instalar o ejecutar code que introduzca o cambie funciones o la funcionalidad de la app, incluyendo otras apps.
Leído por sí solo, parece una prohibición. La excepción está en el segundo texto, sección 3.3.1(B) del Acuerdo de licencia del Apple Developer Program, que todo desarrollador firma:
Se puede descargar code interpretado en una Aplicación, pero solo siempre que dicho code: (a) no cambie el propósito principal de la Aplicación mediante funciones o funcionalidades inconsistentes con el propósito previsto y anunciado de la Aplicación tal como se envió a la App Store, (b) no cree una tienda para otros code o aplicaciones, y (c) no eluda el firmado, el sandbox u otras funciones de seguridad del SO.
Así que la regla no es “no descargar code”. Es “no descargar parte nativa code, y solo permitir code interpretado bajo tres condiciones”.
La capa web de una app Capacitor es JavaScript, HTML y CSS que se ejecutan en WKWebView, que es el propio motor WebKit de Apple. Eso se interpreta como code, así que entra en la excepción. La directriz 4.7 va en la misma línea: Apple permite explícitamente que las apps ejecuten contenido HTML5 y JavaScript que no esté incrustado en el binario.
Dónde está el límite
| Permitido con un live update | No permitido con un live update |
|---|---|
| Correcciones de bugs en tu JavaScript, HTML o CSS | Descargar Swift, Objective-C o cualquier binario compilado |
| Cambios de UI, de copy o nuevas pantallas en tu stack web actual | Transformar la app en un producto distinto (de una app de notas a un casino) |
| A/B tests y rollouts graduales de web code | Desbloquear funciones ocultas a App Review |
| Actualizar imágenes, traducciones o config | Crear una tienda que instale otras apps o code |
| Revertir un release fallido | Evadir el sandbox, la firma o los permisos de iOS |
Capgo solo envía la columna izquierda. Reemplaza el web bundle dentro de tu app. Cualquier cambio nativo, como un nuevo plugin Capacitor, un nuevo permiso o una actualización de SDK, requiere un release regular en la App Store. Los Capgo segmentación por versión aseguran que un bundle que requiere nuevos code nativos nunca llegue a un binario antiguo.
Cómo lo aplica Apple
Apple evalúa el fondo, no la tecnología. Nadie será sancionado por corregir un typo vía OTA. El patrón que Apple persigue es una app que pasa la revisión siendo una cosa y se convierte en otra después. Eso infringe la guía 2.3.1 (sin funciones ocultas) tanto como la 2.5.2.
En la práctica:
- Envía lo que habrías subido, solo que más rápido.
- Mantén cada update dentro del propósito descrito en tu ficha de la App Store.
- Lanza las grandes funcionalidades vía App Review, y usa live updates para fixes e iteraciones entre releases.
- Nunca uses un live update para activar comportamientos que los reviewers no vieron.
Si sigues eso, los Live Updates son una parte normal al lanzar una app de iOS. Los equipos de React Native lo han hecho por años con CodePush y Expo Updates, y los equipos de Capacitor lo hacen con Capgo.
¿Qué stacks pueden hacerlo en iOS?
Si tu app puede enviar actualizaciones over-the-air en iOS depende de una pregunta: ¿tu lógica de app se interpreta en runtime? JavaScript y otros code interpretados, sí. Swift, Objective-C y C++ compilados a code de máquina, no. Los frameworks con compilación AOT como Flutter solo califican mediante un intérprete.
Compatibilidad de live update en iOS por stack
| Stack | Cómo se ejecuta el code en iOS | ¿Permite Live Updates? | Herramientas |
|---|---|---|---|
| Capacitor | JavaScript, HTML, CSS en WKWebView (WebKit) | Sí | Capgo |
| Ionic (en Capacitor) | Igual que Capacitor | Sí | Capgo |
| Cordova | JavaScript en WKWebView | Sí | Capgo tras migrar a Capacitor, plugins legacy de Cordova |
| React Native / Expo | Bundle de JavaScript en Hermes o JavaScriptCore | Sí, solo JavaScript | Expo Updates, alternativas self-hosted a CodePush |
| NativeScript | JavaScript en un motor embebido | Sí, solo JavaScript | Limitado, mayormente propio |
| Flutter | Dart compilado AOT a code de máquina | Solo mediante un intérprete | Shorebird (intérprete de Dart para parches) |
| Swift / Objective-C nativo | code de máquina | No para code nativo; sí para JavaScript en WebKit o JavaScriptCore | Configuración remota y UI server-driven |
| .NET MAUI / Xamarin | C# compilado AOT a code de máquina | No | Solo configuración remota |
| Kotlin / Compose Multiplatform | Kotlin/Native compilado a code de máquina | No | Solo configuración remota |
| Unity / Unreal | C# vía IL2CPP o C++, compilado | No para code, sí para el contenido | Asset bundles, contenido con scripts (Lua) |
| Web wrapper (URL remota) | Sitio web cargado en un WebView | Siempre en vivo, pero con riesgo de revisión | Ninguna necesaria, ver nota abajo |
Capacitor, Ionic y Cordova: totalmente cubiertos
La UI web y la lógica de negocio en JS de tu app corren en WKWebView, mientras que el shell nativo y los plugins siguen siendo nativos. La sección 3.3.1(B) del Apple Developer Program License Agreement permite code interpretado descargado solo si mantiene el propósito principal de la app, no crea una code storefront y no evade la seguridad del OS. La Guideline 4.7 regula por separado las apps que ofrecen mini apps en HTML5 y JavaScript y añade requisitos adicionales.
Un live update reemplaza el web bundle. El shell nativo, los plugins y los permisos siguen siendo los que Apple revisó. Por eso Capgo es compliant por diseño: no puede cambiar el code nativo aunque lo intentes. Los nuevos plugins o permisos nativos aún requieren un release en la App Store.
React Native y Expo: JavaScript sí, módulos nativos no
React Native ejecuta tu JS bundle en Hermes o JavaScriptCore. Ese bundle es code interpretado y puede actualizarse over the air, que es para lo que fueron creados Expo Updates y Microsoft CodePush (retirado en 2025). Equipos dejando CodePush buscan un reemplazo.
Cualquier cambio en módulos nativos, la versión de React Native o Info.plist requiere un nuevo binario.
Flutter: solo mediante un intérprete
En iOS, Flutter compila Dart de forma anticipada a code. Descargar nuevo code está prohibido, por lo que el Flutter estándar no puede usar live updates. Shorebird lo resuelve ejecutando code de Dart parcheado en un intérprete, lo que entra en la excepción de code. Lee más en live updates para apps de Flutter.
Swift nativo, .NET MAUI, Kotlin Multiplatform: sin actualizaciones code nativas
Estos stacks generan code nativo. No pueden descargar code nativo de reemplazo. Una app nativa aún puede descargar y ejecutar code interpretado, como JavaScript vía JavaScriptCore, si cumple las condiciones de Apple. Lo que también puedes hacer OTA es cambiar datos: remote config, feature flags de funciones ya revisadas, server-driven UI, imágenes y copy.
Unity y motores de juego: contenido sí, code no
El code del juego está compilado. Los asset bundles (niveles, arte, datos de balanceo) son contenido y se pueden descargar. Lenguajes de scripting embebidos como Lua son code interpretados y siguen las mismas reglas que JavaScript.
Wrappers de URL remotos: en vivo, pero con riesgo de revisión
Una app que solo carga tu web en un WebView se "actualiza" cada vez que despliegas el sitio. El problema no es la directriz 2.5.2, sino la 4.2 (funcionalidad mínima): Apple rechaza apps que son solo un sitio web en un frame. Empaquetar la web app con Capacitor, añadir funciones nativas y usar live updates evita esto.
Lo que ningún stack puede hacer en iOS
Sea cual sea tu framework, un live update no puede:
- Descargar code nativo, frameworks o librerías dinámicas
- Añadir nuevos permisos o entitlements
- Cambiar la app a algo que no describe su ficha en la App Store
- Activar funciones que se ocultaron durante el App Review
Próximos pasos
- Respuesta de Android: ¿Permite Google los live updates sin revisión de la Play Store?
- Detalles de la aplicación de reglas: Cómo Apple aplica las restricciones de actualizaciones OTA
- Flujo de aprobación: Capacitor Actualizaciones OTA: guía de aprobación de App Store
- Historias reales de rechazo: Historias de terror de rechazos en App Store
Lanza fixes hoy, no tras la revisión
actualizaciones Live Update de Capgo envía cambios de JavaScript, HTML y CSS a tu app Capacitor en minutos, con canales, rollbacks, actualizaciones delta y cifrado de extremo a extremo. Es open source y puedes autoalojarlo.
bunx @capgo/cli@latest init
Sigue la quickstart para enviar tu primer update.