Risposta breve: sì, Apple consente aggiornamenti live, entro certi limiti. Puoi inviare nuovo JavaScript, HTML e CSS a un'app iOS senza una nuova revisione dell'App Store, purché l'aggiornamento non cambi la natura dell'app. Non puoi scaricare code nativo.
Con Capgo: Capgo live updates distribuisce solo il layer web (JavaScript, HTML, CSS, asset) di un'app Capacitor, cosa che le regole di Apple consentono quando l'aggiornamento mantiene lo scopo principale dell'app, non crea un code storefront e non aggira la sicurezza del sistema operativo; le modifiche native passano comunque da un rilascio sullo store.
Gran parte della confusione nasce dal mescolare due cose diverse: gli aggiornamenti live di code interpretato (consentiti) e il download di nuovo code eseguibile (non consentito). Questa pagina cita le regole, mostra dov'è il confine e spiega come Apple le fa rispettare.
Non è consulenza legale. È come recitano oggi le regole e come migliaia di app le usano in produzione.
Cosa dicono davvero le regole di Apple
Contano due testi. Il primo è Linea guida 2.5.2 dell'App Store Review:
Le app devono essere autosufficienti nei loro bundle e non possono leggere o scrivere dati al di fuori dell'area del container designata, né possono scaricare, installare o eseguire code che introduca o modifichi funzionalità dell'app, incluse altre app.
Preso così, sembra quasi un divieto. L'eccezione si trova invece nel secondo testo, sezione 3.3.1(B) di Contratto di licenza Apple Developer Program, che ogni sviluppatore firma:
Gli code interpretati possono essere scaricati in un'Applicazione, ma solo a patto che tale code: (a) non cambi lo scopo primario dell'Applicazione fornendo funzionalità incoerenti con lo scopo dichiarato e pubblicizzato dell'Applicazione inviata all'App Store, (b) non crei uno store o una vetrina per altri code o applicazioni, e (c) non aggiri la firma, il sandbox o altre funzioni di sicurezza del sistema operativo.
Quindi la regola non è "niente code scaricati". È "niente nativo code scaricati, e code interpretati solo a tre condizioni".
Il web layer di un'app Capacitor è JavaScript, HTML e CSS in esecuzione in WKWebView, che è il motore WebKit di Apple. Viene interpretato code, quindi rientra nell'eccezione. La Linea guida 4.7 va nella stessa direzione: Apple consente esplicitamente alle app di eseguire contenuti HTML5 e JavaScript non incorporati nel binario.
Dove sta la linea
| Consentito con live update | Non consentito con live update |
|---|---|
| Bug fix in JavaScript, HTML o CSS | Scaricare Swift, Objective-C o qualsiasi binario compilato |
| Modifiche UI, testi o nuove schermate nel web stack esistente | Trasformare l'app in un prodotto diverso (un'app di note che diventa un casinò) |
| Test A/B e rollout graduale di web code | Sbloccare funzionalità nascoste all'App Review |
| Aggiornamento di immagini, traduzioni e config | Creare uno store che installa altre app o code |
| Fare il rollback di un rilascio errato | Eludere il sandbox di iOS, la firma o i permessi |
Capgo distribuisce solo la colonna sinistra. Sostituisce il web bundle all'interno della tua app. Tutto ciò che è nativo, come un nuovo plugin Capacitor, un nuovo permesso o un upgrade di SDK, richiede comunque un rilascio regolare su App Store. Capgo’s targeting delle versioni assicura che un bundle che richiede nuovi code nativi non raggiunga mai un binario vecchio.
Come Apple le applica
Apple valuta la sostanza, non la tecnologia. Nessuno viene rimosso per aver corretto un refuso in modalità over the air. Il modello che Apple insegue è un'app che supera la revisione come una cosa e poi diventa un'altra. Si tratta della direttiva 2.3.1 (nessuna funzione nascosta o non documentata) tanto quanto della 2.5.2.
In pratica:
- Pubblica ciò che avresti inviato, ma più velocemente.
- Mantieni ogni aggiornamento all'interno dello scopo descritto nel tuo listing su App Store.
- Invia i grandi lanci di funzionalità ad App Review e usa le live update per correzioni e iterazioni tra un rilascio e l'altro.
- Non usare mai un live update per attivare un comportamento che i revisori non hanno visto.
Se segui questa strada, gli aggiornamenti live sono una parte normale del rilascio di un'app iOS. I team React Native lo fanno da anni con CodePush ed Expo Updates, e i team Capacitor lo fanno con Capgo.
Quali stack possono farlo su iOS?
La possibilità di inviare aggiornamenti over-the-air su iOS dipende da una domanda: la logica della tua app viene interpretata a runtime? JavaScript e altri code interpretati, sì. Swift, Objective-C e C++ compilati in code, no. I framework con compilazione AOT come Flutter sono compatibili solo tramite un interprete.
Compatibilità live update su iOS per stack
| Stack | Come gira il code su iOS | Aggiornamenti live consentiti? | Strumenti |
|---|---|---|---|
| Capacitor | JavaScript, HTML, CSS in WKWebView (WebKit) | Sì | Capgo |
| Ionic (su Capacitor) | Uguale a Capacitor | Sì | Capgo |
| Cordova | JavaScript in WKWebView | Sì | Capgo dopo la migrazione a Capacitor, plugin Cordova legacy |
| React Native / Expo | JavaScript bundle su Hermes o JavaScriptCore | Sì, solo JavaScript | Expo Updates, alternative self-hosted a CodePush |
| NativeScript | JavaScript su un motore embedded | Sì, solo JavaScript | Limitata, in gran parte self-built |
| Flutter | Dart compilato AOT in machine code | Solo tramite un interprete | Shorebird (interprete Dart per patch) |
| Swift / Objective-C nativo | Macchina code | No per il code nativo; sì per JavaScript in WebKit o JavaScriptCore | Remote config e UI server-driven |
| .NET MAUI / Xamarin | C# compilato AOT in machine code | No | Solo remote config |
| Kotlin / Compose Multiplatform | Kotlin/Native compilato in code macchina | No | Solo remote config |
| Unity / Unreal | C# via IL2CPP o C++, compilati | No per code, sì per i contenuti | Asset bundle, contenuti scriptati (Lua) |
| Web wrapper (URL remoto) | Sito web caricato in una WebView | Sempre live, ma rischio di revisione | Non necessario, vedi nota qui sotto |
Capacitor, Ionic e Cordova: copertura totale
L'interfaccia web e la logica di business in JavaScript della tua app girano in WKWebView, mentre la shell nativa e i plugin restano nativi. La sezione 3.3.1(B) del Developer Program License Agreement di Apple consente il download di codice interpretato code solo se preserva lo scopo principale dell'app, non crea uno storefront code e non aggira la sicurezza del sistema operativo. La linea guida 4.7 disciplina separatamente le app che offrono mini app HTML5 e JavaScript e introduce requisiti aggiuntivi.
Un live update sostituisce il bundle web. La shell nativa, i plugin e le autorizzazioni restano quelli approvati da Apple. È per questo che Capgo è conforme by design: non può modificare il code nativo, nemmeno se lo volessi. Nuovi plugin nativi o autorizzazioni richiedono comunque un rilascio su App Store.
React Native ed Expo: JavaScript sì, moduli nativi no
React Native esegue il tuo bundle JavaScript su Hermes o JavaScriptCore. Quel bundle è codice interpretato code e può essere aggiornato over the air, ed è esattamente per questo che sono nati Expo Updates e Microsoft CodePush (ritirato nel 2025). I team che abbandonano CodePush richiedono una sostituzione.
Qualsiasi modifica ai moduli nativi, alla versione di React Native o a Info.plist richiede un nuovo binario.
Flutter: solo tramite un interprete
On iOS, Flutter compiles Dart ahead of time to ARM machine code. Downloading new machine code is forbidden, so stock Flutter cannot use live updates. Shorebird solves this by running patched Dart code in an interpreter, which brings it under the interpreted code exception. Read more in live updates per app Flutter.
Swift nativo, .NET MAUI, Kotlin Multiplatform: niente update nativi code
Questi stack producono codice macchina nativo code. Non possono scaricare codice nativo sostitutivo code. Un'app nativa può comunque scaricare ed eseguire codice interpretato code, come JavaScript tramite JavaScriptCore, a condizione che rispetti i requisiti di Apple. Quello che puoi fare anche over the air è modificare i dati: remote config, feature flag per funzionalità già revisionate, UI server-driven, immagini e testi.
Unity e motori di gioco: contenuti sì, code no
Il gioco code viene compilato. I bundle di asset (livelli, grafica, dati di bilanciamento) sono contenuti e possono essere scaricati. I linguaggi di scripting incorporati come Lua vengono interpretati code e seguono le stesse regole di JavaScript.
Wrapper con URL remoti: live, ma rischiosi per la review
Un’app che carica solo il tuo sito web in una WebView viene “aggiornata” a ogni deploy del sito. Il problema non è la guideline 2.5.2, ma la guideline 4.2 (funzionalità minima): Apple rifiuta le app che sono solo un sito web in un frame. Fare il bundle dell’app web con Capacitor, aggiungere funzionalità native e usare le live update evita questo problema.
Cosa non può fare nessuno stack su iOS
Qualunque sia il tuo framework, un live update non può:
- Scarica i file nativi code, i framework o le librerie dinamiche
- Aggiungere nuove autorizzazioni o entitlements
- Trasformare l'app in qualcosa che la scheda App Store non descrive
- Attivare funzionalità nascoste alla App Review
Cosa fare ora
- Risposta per Android: Google consente live updates senza revisione Play Store?
- Applicazione nel dettaglio: Come Apple applica le restrizioni sugli aggiornamenti OTA
- Workflow di approvazione: Aggiornamenti OTA Capacitor: guida all'approvazione App Store
- Storie reali di rifiuto: Storie horror di rifiuto dall'App Store
Rilascia fix oggi, non dopo la revisione
Live updates di Capgo pubblica modifiche JavaScript, HTML e CSS nella tua app Capacitor in pochi minuti, con canali, rollback, delta update e crittografia end-to-end. È open source e può essere self-hosted.
bunx @capgo/cli@latest init
Segui lo standard quickstart per inviare il tuo primo update.