Bitcode — to pośrednia reprezentacja programu na etapie kompilacji aplikacji iOS. W przeciwieństwie do kodu maszynowego, Bitcode nie jest związany z konkretną architekturą procesora. Według Apple Developer Documentation, App Store jest w stanie przekompilować Bitcode pod docelową architekturę, co zwiększa wydajność i zmniejsza rozmiar pliku instalacyjnego. Deweloper wysyła Bitcode do App Store, a sklep sam generuje zoptymalizowany plik binarny dla każdego typu urządzenia.
Najważniejsze
Bitcode stanowi pośrednią reprezentację programu (Intermediate Representation, IR), którą generuje infrastruktura kompilatora LLVM. Apple wprowadziła wsparcie dla Bitcode począwszy od Xcode 7 i iOS 9 jako obowiązkowy wymóg dla aplikacji watchOS i opcjonalny dla iOS oraz tvOS. Od Xcode 14 obowiązkowość została zniesiona dla wszystkich platform z wyjątkiem watchOS.
Koncepcja pośredniej reprezentacji kodu istnieje od lat 2000. w ramach projektu LLVM, założonego przez Chrisa Lattnera na Uniwersytecie Illinois. Apple zaadaptowała LLVM dla Xcode w 2011 roku, a w 2015 przedstawiła Bitcode jako sposób aktualizacji aplikacji bez ponownego wysyłania do App Store. Technologia została ogłoszona na WWDC 2015 w sesji “What’s New in Xcode”.
Kod maszynowy — to instrukcje binarne dla konkretnego procesora: arm64, armv7 lub x86_64. Bitcode jest przechowywany w formacie niezależnym od sprzętu, co pozwala App Store generować zoptymalizowane pliki binarne dla różnych architektur z jednej reprezentacji źródłowej. To kluczowa różnica determinująca wszystkie zalety technologii.
| Cecha | Bitcode | Kod maszynowy |
|---|---|---|
| Zależność od architektury | Niezależny | Przywiązany do CPU |
| Rozmiar pliku binarnego | Kompaktowy | Większy |
| Możliwość rekompilacji | Tak | Nie |
| Wsparcie App Store | Rekompilowany | Używany bez zmian |
| Debugowanie | Ograniczone | Pełne wsparcie |
Bitcode nie jest plikiem wykonywalnym. To LLVM IR w formacie binarnym, który deweloper wysyła do App Store wraz z metadanymi projektu. Sklep z aplikacjami uruchamia proces rekompilacji, dostosowując kod do każdej docelowej platformy i wersji systemu operacyjnego.
Proces generowania Bitcode rozpoczyna się od frontendu kompilatora, który przekształca kod źródłowy Swift lub Objective-C w LLVM IR. Na etapie linkowania Xcode pakuje IR do plików w formacie .bc (Bitcode), które następnie są wysyłane do App Store wraz z archiwum .xcarchive. App Store z kolei uruchamia proces rekompilacji po swojej stronie.
Infrastruktura LLVM składa się z trzech części: frontendu (Clang dla C/ObjC, Swift Frontend dla Swift), optymalizatora Middle-End i backendu (generator kodu maszynowego). Bitcode — to wynik pracy pierwszych dwóch etapów bez przejścia do generowania instrukcji asemblerowych. Middle-End wykonuje optymalizacje niezależne od platformy: usuwanie martwego kodu, inlining i składanie stałych.
// Przykładowy kod źródłowy Swift
func calculateSum(a: Int, b: Int) -> Int {
return a + b
}
// LLVM IR po kompilacji (uproszczony)
; define i32 @calculateSum(i32 %a, i32 %b)
; %result = add i32 %a, %b
; ret i32 %result
Po wygenerowaniu IR kompilator wykonuje serię optymalizacji na poziomie reprezentacji: usuwanie martwego kodu, inlining funkcji i składanie stałych. Te optymalizacje nie zależą od architektury i są zachowywane w Bitcode. Podczas rekompilacji w App Store dodawane są optymalizacje zależne od architektury, takie jak przestawianie instrukcji dla konkretnego procesora.
App Store Connect przyjmuje archiwum z Bitcode i uruchamia własną infrastrukturę kompilacji. System określa docelową architekturę urządzenia użytkownika i generuje kod maszynowy, dodatkowo optymalizując go pod konkretne cechy procesora. Dla arm64e (procesory A12+ i serii M) stosowane są dodatkowe optymalizacje bezpieczeństwa.
Ten proces nazywa się App Thinning — technologia pozwalająca dostarczać na urządzenie tylko te zasoby i kod, które są niezbędne dla jego architektury. Użytkownik iPhone’a z procesorem A17 Pro otrzymuje plik binarny zoptymalizowany pod arm64e, bez zbędnych instrukcji dla przestarzałych architektur. To skraca czas ładowania i oszczędza miejsce na urządzeniu.
Bitcode zapewnia kilka kluczowych zalet dla deweloperów aplikacji iOS. Główna z nich — automatyczna optymalizacja pod nowe procesory Apple bez ponownego publikowania aktualizacji w App Store. Jest to szczególnie istotne przy przejściu na nowe architektury, takie jak przejście z armv7 na arm64.
Kiedy Apple wypuszcza procesor z nową architekturą, aplikacje wysłane z Bitcode są automatycznie przekompilowywane pod nią. Deweloper nie musi ponownie składać projektu i publikować aktualizacji — App Store robi to po swojej stronie przy pierwszym pobraniu przez użytkownika. Jest to szczególnie ważne dla długożyjących aplikacji, które są wspierane przez lata.
App Thinning w połączeniu z Bitcode pozwala zmniejszyć rozmiar instalowanej aplikacji o 15–40%. App Store generuje tylko te instrukcje maszynowe, które są potrzebne konkretnemu urządzeniu, wykluczając kod dla innych architektur i warianty dla różnych wersji iOS. W praktyce oznacza to, że użytkownik z nowym iPhonem otrzymuje kompaktowy plik binarny.
Według danych Apple WWDC 2015 Session 102, użycie Bitcode i App Thinning może zmniejszyć rozmiar pobieranej aplikacji średnio o 25% w porównaniu z uniwersalnym plikiem binarnym zawierającym wszystkie architektury. Dla aplikacji o rozmiarze 100 MB oszczędność może wynieść do 40 MB na urządzeniu użytkownika.
Konfiguracja Bitcode jest wykonywana w konfiguracji kompilacji Xcode. Parametr Enable Bitcode znajduje się w ustawieniach Build Settings i domyślnie jest włączony dla nowych projektów, ale deweloperzy mogą go wyłączyć do debugowania lub przy używaniu bibliotek stron trzecich bez wsparcia Bitcode.
// Build Settings -> Apple Clang - Code Generation
// Enable Bitcode = YES
// Lub przez Info.plist dla poszczególnych targetów
@property (nonatomic, assign) BOOL enableBitcode;
- (void)configureBuildSettings {
// Sprawdzenie statusu Bitcode w konfiguracji
if (self.enableBitcode) {
NSLog(@"Bitcode is enabled for this target");
} else {
NSLog(@"Bitcode is disabled");
}
}
Aby sprawdzić, czy archiwum zawiera Bitcode, otwórz plik .xcarchive przez Xcode Organizer lub wykonaj polecenie otool -l w Terminalu. Obecność sekcji __LLVM w pliku binarnym potwierdza, że Bitcode jest włączony i poprawnie spakowany. Jeśli sekcji brak — Bitcode nie został wygenerowany podczas kompilacji.
# Sprawdzenie obecności Bitcode w archiwum
otool -l YourApp.app/YourApp | grep __LLVM
# Wynik: jeśli jest sekcja __LLVM — Bitcode jest obecny
# Jeśli wynik jest pusty — Bitcode nie jest włączony lub nie został wygenerowany
# Można również sprawdzić za pomocą polecenia size
size -m -l YourApp.app/YourApp | grep __LLVM
Przy używaniu bibliotek stron trzecich przez CocoaPods lub SPM upewnij się, że wszystkie zależności są zbudowane z Bitcode. Jeśli choć jedna biblioteka nie wspiera Bitcode, Xcode wygeneruje błąd linkowania na etapie archiwizacji. Dla CocoaPods sprawdź flagę bitcode_enabled w podspecach lub użyj use_frameworks! z enable_bitcode.
Bitcode nie jest uniwersalnym rozwiązaniem dla wszystkich typów projektów iOS. Technologia ma ograniczenia, które deweloper powinien wziąć pod uwagę przed włączeniem opcji w konfiguracji kompilacji. Zrozumienie tych ograniczeń pomaga uniknąć problemów na etapie archiwizacji i publikacji.
Nie wszystkie biblioteki stron trzecich są dostarczane z wsparciem Bitcode. Jeśli biblioteka jest dystrybuowana tylko w postaci skompilowanego pliku binarnego bez Bitcode, projekt z włączoną opcją nie zbuduje się. W takim przypadku deweloper będzie musiał albo wyłączyć Bitcode, albo poprosić dostawcę o wersję z Bitcode. Jest to szczególnie istotne dla starych bibliotek, które nie są już aktualizowane.
Raporty awarii z aplikacji zbudowanych z Bitcode wymagają dodatkowego przetwarzania. Symbole (dSYM) dla przekompilowanego kodu są generowane przez App Store i dostępne do pobrania przez Xcode Organizer. Bez pobrania odpowiednich plików dSYM stos wywołań w raportach awarii będzie nieczytelny, co utrudnia diagnozowanie problemów.
Według stanu na iOS 17 i Xcode 15 Apple nie wymaga obowiązkowego włączania Bitcode do publikacji w App Store. Jednak dla aplikacji watchOS Bitcode pozostaje obowiązkowym warunkiem ustawionym na poziomie reguł App Store Connect. Deweloperom zaleca się włączanie Bitcode dla nowych projektów, jeśli wszystkie zależności go wspierają.
Często zadawane pytania
Dla aplikacji iOS i tvOS Bitcode nie jest obowiązkowy począwszy od Xcode 14. Dla watchOS wsparcie Bitcode pozostaje obowiązkowe. Apple zaleca włączanie Bitcode dla nowych projektów, ale nie blokuje publikacji bez niego.
Bitcode pozwala App Store stosować App Thinning — generowanie kodu maszynowego tylko dla architektury urządzenia użytkownika. To zmniejsza rozmiar pobieranego pliku binarnego o 15–40% w zależności od liczby wspieranych architektur w projekcie.
Tak, pliki dSYM są niezbędne do symbolizacji raportów awarii z przekompilowanych plików binarnych. App Store udostępnia możliwość pobrania dSYM przez Xcode Organizer po przetworzeniu archiwum. Bez nich stos wywołań w Crashlytics i konsoli będzie zawierał tylko adresy pamięci.
SPM wspiera Bitcode, jeśli zależności są dystrybuowane w kodzie źródłowym, a nie w postaci plików binarnych. Zależności binarne przez SPM muszą dostarczać wersję z Bitcode, w przeciwnym razie projekt z włączoną opcją nie skompiluje się.
Bitcode — to niezależna od sprzętu pośrednia reprezentacja LLVM IR, która nie może być bezpośrednio wykonana przez procesor. Kod maszynowy zawiera gotowe instrukcje dla konkretnej architektury (arm64, x86_64) i jest wykonywany bez dodatkowej kompilacji.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również