Bitcode è una rappresentazione intermedia di un programma nella fase di compilazione di un'applicazione iOS. A differenza del codice macchina, Bitcode non è legato a un'architettura di processore specifica. Secondo la Apple Developer Documentation, l'App Store può ricompilare Bitcode per l'architettura di destinazione, migliorando le prestazioni e riducendo le dimensioni del file di installazione. Lo sviluppatore invia Bitcode all'App Store e il negozio stesso genera un file binario ottimizzato per ogni tipo di dispositivo.
Punti Chiave
Bitcode è una rappresentazione intermedia di un programma (Intermediate Representation, IR) generata dall'infrastruttura del compilatore LLVM. Apple ha introdotto il supporto per Bitcode a partire da Xcode 7 e iOS 9 come requisito obbligatorio per le applicazioni watchOS e facoltativo per iOS e tvOS. A partire da Xcode 14, il requisito è stato rimosso per tutte le piattaforme eccetto watchOS.
Il concetto di rappresentazione intermedia del codice esiste dagli anni 2000 come parte del progetto LLVM, fondato da Chris Lattner all'Università dell'Illinois. Apple ha adattato LLVM per Xcode nel 2011 e, nel 2015, ha presentato Bitcode come un modo per aggiornare le applicazioni senza doverle inviare nuovamente all'App Store. La tecnologia è stata annunciata al WWDC 2015 nella sessione “What's New in Xcode”.
Il codice macchina consiste in istruzioni binarie per un processore specifico: arm64, armv7 o x86_64. Bitcode viene memorizzato in un formato indipendente dall'hardware, consentendo all'App Store di generare file binari ottimizzati per diverse architetture da un'unica rappresentazione sorgente. Questa differenza fondamentale definisce tutti i vantaggi della tecnologia.
| Caratteristica | Bitcode | Codice macchina |
|---|---|---|
| Dipendenza dall'architettura | Indipendente | Legato alla CPU |
| Dimensione del file binario | Compatto | Più grande |
| Capacità di ricompilazione | Sì | No |
| Supporto App Store | Viene ricompilato | Viene usato così com'è |
| Debug | Limitato | Supporto completo |
Bitcode non è un file eseguibile. È LLVM IR in formato binario che lo sviluppatore invia all'App Store insieme ai metadati del progetto. Il negozio di applicazioni esegue il processo di ricompilazione, adattando il codice per ogni piattaforma di destinazione e versione del sistema operativo.
Il processo di generazione di Bitcode inizia con il frontend del compilatore, che converte il codice sorgente Swift o Objective-C in LLVM IR. Nella fase di collegamento, Xcode impacchetta l'IR in file in formato .bc (Bitcode), che vengono poi inviati all'App Store insieme all'archivio .xcarchive. L'App Store, a sua volta, esegue il processo di ricompilazione dal suo lato.
L'infrastruttura LLVM è composta da tre parti: il frontend (Clang per C/ObjC, Swift Frontend per Swift), l'ottimizzatore Middle-End e il backend (generatore di codice macchina). Bitcode è il risultato delle prime due fasi senza procedere alla generazione di istruzioni assembly. Il Middle-End esegue ottimizzazioni indipendenti dalla piattaforma: eliminazione del codice morto, inlining e folding delle costanti.
// Esempio di codice sorgente Swift
func calculateSum(a: Int, b: Int) -> Int {
return a + b
}
// LLVM IR dopo la compilazione (semplificato)
; define i32 @calculateSum(i32 %a, i32 %b)
; %result = add i32 %a, %b
; ret i32 %result
Dopo la generazione dell'IR, il compilatore esegue una serie di ottimizzazioni a livello di rappresentazione: eliminazione del codice morto, inlining di funzioni e folding delle costanti. Queste ottimizzazioni sono indipendenti dall'architettura e vengono preservate in Bitcode. Durante la ricompilazione nell'App Store, vengono aggiunte ottimizzazioni dipendenti dall'architettura, come il riordinamento delle istruzioni per un processore specifico.
App Store Connect riceve l'archivio con Bitcode ed esegue la propria infrastruttura di compilazione. Il sistema determina l'architettura di destinazione del dispositivo dell'utente e genera codice macchina, ottimizzandolo ulteriormente per le caratteristiche specifiche del processore. Per arm64e (processori A12+ e serie M), vengono applicate ottimizzazioni di sicurezza aggiuntive.
Questo processo si chiama App Thinning — una tecnologia che consegna a un dispositivo solo le risorse e il codice necessari per la sua architettura. Un utente con un iPhone con processore A17 Pro riceve un file binario ottimizzato per arm64e, senza istruzioni superflue per architetture più vecchie. Questo riduce i tempi di download e risparmia spazio sul dispositivo.
Bitcode offre diversi vantaggi chiave per gli sviluppatori di applicazioni iOS. Il principale è l'ottimizzazione automatica per i nuovi processori Apple senza dover inviare nuovamente un aggiornamento all'App Store. Questo è particolarmente rilevante quando si passa a nuove architetture, come il passaggio da armv7 ad arm64.
Quando Apple rilascia un processore con una nuova architettura, le applicazioni inviate con Bitcode vengono automaticamente ricompilate per essa. Lo sviluppatore non deve ricostruire il progetto e pubblicare un aggiornamento — l'App Store lo fa dal suo lato al primo download da parte dell'utente. Questo è particolarmente importante per le applicazioni a lunga durata che vengono mantenute per anni.
App Thinning combinato con Bitcode può ridurre le dimensioni dell'applicazione installata dal 15 al 40%. L'App Store genera solo le istruzioni macchina necessarie per un dispositivo specifico, eliminando il codice per altre architetture e variazioni per diverse versioni di iOS. In pratica, ciò significa che un utente con un nuovo iPhone riceve un file binario compatto.
Secondo Apple WWDC 2015 Session 102, l'uso di Bitcode e App Thinning può ridurre le dimensioni dell'applicazione scaricata in media del 25% rispetto a un file binario universale contenente tutte le architetture. Per un'applicazione di 100 MB, il risparmio può arrivare fino a 40 MB sul dispositivo dell'utente.
La configurazione di Bitcode viene effettuata nelle impostazioni di build di Xcode. Il parametro Enable Bitcode si trova nelle Build Settings ed è abilitato per impostazione predefinita per i nuovi progetti, ma gli sviluppatori possono disabilitarlo per il debug o quando utilizzano librerie di terze parti senza supporto per Bitcode.
// Build Settings -> Apple Clang - Code Generation
// Enable Bitcode = YES
// O tramite Info.plist per singoli target
@property (nonatomic, assign) BOOL enableBitcode;
- (void)configureBuildSettings {
// Verifica dello stato di Bitcode nella configurazione
if (self.enableBitcode) {
NSLog(@"Bitcode is enabled for this target");
} else {
NSLog(@"Bitcode is disabled");
}
}
Per verificare se l'archivio contiene Bitcode, aprire il file .xcarchive tramite Xcode Organizer o eseguire il comando otool -l nel Terminale. La presenza di una sezione __LLVM nel file binario conferma che Bitcode è abilitato e correttamente impacchettato. Se la sezione è assente, Bitcode non è stato generato durante la build.
# Verifica della presenza di Bitcode nell'archivio
otool -l YourApp.app/YourApp | grep __LLVM
# Output: se c'è una sezione __LLVM — Bitcode è presente
# Se l'output è vuoto — Bitcode non è abilitato o non è stato generato
# È possibile verificare anche con il comando size
size -m -l YourApp.app/YourApp | grep __LLVM
Quando si utilizzano librerie di terze parti tramite CocoaPods o SPM, assicurarsi che tutte le dipendenze siano compilate con Bitcode. Se almeno una libreria non supporta Bitcode, Xcode genererà un errore di collegamento durante l'archiviazione. Per CocoaPods, verificare il flag bitcode_enabled nelle subspec o utilizzare use_frameworks! con enable_bitcode.
Bitcode non è una soluzione universale per tutti i tipi di progetti iOS. La tecnologia ha limitazioni che lo sviluppatore deve considerare prima di abilitare l'opzione nella configurazione di build. Comprendere queste limitazioni aiuta a evitare problemi durante l'archiviazione e la pubblicazione.
Non tutte le librerie di terze parti vengono fornite con il supporto per Bitcode. Se una libreria viene distribuita solo come file binario compilato senza Bitcode, il progetto con l'opzione abilitata non verrà compilato. In questo caso, lo sviluppatore dovrà disabilitare Bitcode o richiedere una versione con Bitcode al fornitore. Questo è particolarmente rilevante per le librerie vecchie che non vengono più aggiornate.
Le segnalazioni di crash da applicazioni compilate con Bitcode richiedono un'elaborazione aggiuntiva. I simboli (dSYM) per il codice ricompilato vengono generati dall'App Store e sono disponibili per il download tramite Xcode Organizer. Senza il caricamento dei file dSYM corrispondenti, lo stack di chiamate nelle segnalazioni di crash risulterà illeggibile, rendendo difficile la diagnosi dei problemi.
A partire da iOS 17 e Xcode 15, Apple non richiede l'abilitazione obbligatoria di Bitcode per la pubblicazione sull'App Store. Tuttavia, per le applicazioni watchOS, Bitcode rimane un requisito obbligatorio a livello di politica di App Store Connect. Si raccomanda agli sviluppatori di abilitare Bitcode per i nuovi progetti se tutte le dipendenze lo supportano.
Domande frequenti
Per le applicazioni iOS e tvOS, Bitcode non è obbligatorio a partire da Xcode 14. Per watchOS, il supporto a Bitcode rimane obbligatorio. Apple raccomanda di abilitare Bitcode per i nuovi progetti ma non blocca la pubblicazione senza di esso.
Bitcode consente all'App Store di applicare App Thinning — generare codice macchina solo per l'architettura del dispositivo dell'utente. Ciò riduce le dimensioni del file binario scaricato dal 15 al 40% a seconda del numero di architetture supportate nel progetto.
Sì, i file dSYM sono necessari per simbolizzare le segnalazioni di crash da file binari ricompilati. L'App Store offre la possibilità di scaricare dSYM tramite Xcode Organizer dopo l'elaborazione dell'archivio. Senza di essi, lo stack di chiamate in Crashlytics e nella console conterrà solo indirizzi di memoria.
SPM supporta Bitcode se le dipendenze sono distribuite in codice sorgente anziché come file binari. Le dipendenze binarie tramite SPM devono fornire una versione con Bitcode, altrimenti un progetto con l'opzione abilitata non verrà compilato.
Bitcode è una rappresentazione intermedia LLVM IR indipendente dall'hardware che non può essere eseguita direttamente da un processore. Il codice macchina contiene istruzioni pronte per un'architettura specifica (arm64, x86_64) e viene eseguito senza compilazione aggiuntiva.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche