Jawaban singkatnya: ya, Apple mengizinkan live updates, dalam batas tertentu. Anda bisa push JavaScript, HTML, dan CSS baru ke aplikasi iOS tanpa review App Store baru, selama update tersebut tidak mengubah fungsi utama aplikasi. Anda tidak bisa download native code.
Sebagian besar kebingungan muncul karena mencampur dua hal berbeda: live updates untuk code yang diinterpretasikan (diizinkan) dan download code executable baru (tidak diizinkan). Halaman ini mengutip aturannya, menunjukkan di mana batasnya, dan menjelaskan cara Apple menegakkannya.
Ini bukan nasihat hukum. Ini adalah bunyi aturan saat ini dan bagaimana ribuan aplikasi menggunakannya di produksi.
Apa kata aturan Apple sebenarnya
Ada dua teks penting. Yang pertama adalah Pedoman Peninjauan App Store 2.5.2:
Aplikasi harus self-contained dalam bundle-nya, dan tidak boleh membaca atau menulis data di luar area container yang ditentukan, juga tidak boleh mengunduh, menginstal, atau mengeksekusi code yang memperkenalkan atau mengubah fitur atau fungsionalitas aplikasi, termasuk aplikasi lain.
Jika dibaca sendiri, itu terdengar seperti larangan. Pengecualiannya ada di teks kedua, bagian 3.3.1(B) dari Perjanjian Lisensi Apple Developer Program, yang ditandatangani oleh setiap developer:
code yang diinterpretasikan boleh diunduh ke Aplikasi hanya selama code tersebut: (a) tidak mengubah tujuan utama Aplikasi dengan menyediakan fitur atau fungsionalitas yang tidak konsisten dengan tujuan yang dimaksudkan dan diiklankan dari Aplikasi sebagaimana diajukan ke App Store, (b) tidak membuat toko atau storefront untuk code atau aplikasi lain, dan (c) tidak mem-bypass signing, sandbox, atau fitur keamanan OS lainnya.
Jadi aturannya bukan “tidak ada code yang diunduh”. Melainkan “tidak ada native code yang diunduh, dan code yang diinterpretasikan hanya dalam tiga kondisi”.
Web layer pada aplikasi Capacitor adalah JavaScript, HTML, dan CSS yang berjalan di WKWebView, yang merupakan engine WebKit milik Apple sendiri. Hal ini diinterpretasikan sebagai code, sehingga masuk dalam pengecualian. Guideline 4.7 menyatakan hal yang sama: Apple secara eksplisit mengizinkan aplikasi menjalankan konten HTML5 dan JavaScript yang tidak tertanam dalam binary.
Di mana batasannya
| Diizinkan dengan live update | Tidak diizinkan dengan live update |
|---|---|
| Bug fixes pada JavaScript, HTML, CSS Anda | Mengunduh Swift, Objective-C, atau binary terkompilasi apa pun |
| Perubahan UI, perubahan copy, layar baru pada web stack Anda | Mengubah aplikasi menjadi produk berbeda (misal: aplikasi catatan jadi kasino) |
| A/B test dan rollout bertahap untuk web code | Membuka fitur yang disembunyikan dari App Review |
| Update gambar, translasi, dan konfigurasi | Membangun store untuk instal aplikasi lain atau code |
| Melakukan rollback rilis yang bermasalah | Melewati sandbox, signing, atau izin iOS |
Capgo hanya mengirimkan kolom sebelah kiri. Ini mengganti web bundle di dalam aplikasi Anda. Segala hal yang bersifat native, seperti plugin Capacitor baru, izin baru, atau upgrade SDK, tetap memerlukan rilis App Store reguler. Capgo targeting versi memastikan bundle yang butuh code native baru tidak pernah sampai ke binary lama.
Cara Apple menerapkannya
Apple menilai substansi, bukan teknologi. Tidak ada yang kena masalah hanya karena memperbaiki typo via OTA. Pola yang dikejar Apple adalah aplikasi yang lolos review sebagai satu hal, tapi berubah menjadi hal lain setelahnya. Itu melanggar guideline 2.3.1 (tidak ada fitur tersembunyi atau tidak terdokumentasi) maupun 2.5.2.
Dalam praktiknya:
- Rilis apa yang seharusnya Anda submit, hanya saja lebih cepat.
- Pastikan setiap update tetap sesuai dengan tujuan yang dijelaskan di listing App Store Anda.
- Gunakan App Review untuk peluncuran fitur besar, dan gunakan live updates untuk perbaikan serta iterasi antar rilis.
- Jangan pernah gunakan live update untuk mengaktifkan perilaku yang tidak dilihat oleh reviewer.
Jika Anda mengikuti langkah tersebut, Live Update menjadi bagian normal dalam merilis aplikasi iOS. Tim React Native sudah melakukannya selama bertahun-tahun dengan CodePush dan Expo Updates, dan tim Capacitor melakukannya dengan Capgo.
Stack mana yang bisa melakukannya di iOS?
Apakah aplikasi Anda bisa mengirim update over-the-air di iOS bergantung pada satu pertanyaan: apakah logika aplikasi Anda diinterpretasikan saat runtime? JavaScript dan code terinterpretasi lainnya, ya. Swift, Objective-C, dan C++ yang dikompilasi ke machine code, tidak. Framework yang dikompilasi AOT seperti Flutter hanya bisa melalui interpreter.
Kompatibilitas iOS live update per stack
| Stack | Cara code berjalan di iOS | Live Update diizinkan? | Tooling |
|---|---|---|---|
| Capacitor | JavaScript, HTML, CSS di WKWebView (WebKit) | Ya | Capgo |
| Ionic (pada Capacitor) | Sama dengan Capacitor | Ya | Capgo |
| Cordova | JavaScript di WKWebView | Ya | Capgo setelah migrasi ke Capacitor, plugin Cordova lama |
| React Native / Expo | bundle JavaScript di Hermes atau JavaScriptCore | Ya, hanya JavaScript | Expo Updates, alternatif CodePush self-hosted |
| NativeScript | JavaScript pada engine embedded | Ya, hanya JavaScript | Terbatas, mayoritas buatan sendiri |
| Flutter | Dart dikompilasi AOT ke code mesin | Hanya melalui interpreter | Shorebird (interpreter Dart untuk patch) |
| Native Swift / Objective-C | code mesin | Tidak untuk native code; ya untuk JavaScript di WebKit atau JavaScriptCore | Remote config dan server-driven UI |
| .NET MAUI / Xamarin | C# yang dikompilasi AOT ke machine code | Tidak | Hanya remote config |
| Kotlin / Compose Multiplatform | Kotlin/Native yang dikompilasi ke machine code | Tidak | Hanya remote config |
| Unity / Unreal | C# via IL2CPP atau C++, dikompilasi | Tidak untuk code, ya untuk konten | Asset bundle, konten skrip (Lua) |
| Web wrapper (URL remote) | Website yang dimuat di WebView | Selalu live, tapi berisiko saat review | Tidak perlu, lihat catatan di bawah |
Capacitor, Ionic, dan Cordova: didukung penuh
Web UI dan logika bisnis JavaScript aplikasi Anda berjalan di WKWebView, sementara native shell dan plugin tetap native. Apple Developer Program License Agreement bagian 3.3.1(B) mengizinkan code terinterpretasi yang diunduh hanya jika tetap menjaga tujuan utama aplikasi, tidak membuat code storefront, dan tidak melewati keamanan OS. Guideline 4.7 secara terpisah mengatur aplikasi yang menawarkan mini app HTML5 dan JavaScript serta menambahkan persyaratan tambahan.
live update menggantikan web bundle. Native shell, plugin, dan permission tetap sama dengan yang direview Apple. Itulah mengapa Capgo patuh secara desain: ia tidak bisa mengubah native code meskipun Anda menginginkannya. Plugin atau permission native baru tetap memerlukan rilis App Store.
React Native dan Expo: JavaScript bisa, native modules tidak
React Native menjalankan JavaScript bundle Anda di Hermes atau JavaScriptCore. Bundle tersebut adalah code terinterpretasi dan dapat diupdate secara over-the-air, seperti fungsi Expo Updates dan Microsoft CodePush (pensiun di 2025). Tim yang meninggalkan CodePush butuh pengganti.
Setiap perubahan pada native modules, versi React Native, atau Info.plist membutuhkan binary baru.
Flutter: hanya lewat interpreter
Di iOS, Flutter mengompilasi Dart secara ahead-of-time menjadi ARM machine code. Mengunduh machine code baru dilarang, jadi Flutter standar tidak bisa memakai live updates. Shorebird mengatasinya dengan menjalankan patched Dart code di dalam interpreter, sehingga masuk ke pengecualian code yang diinterpretasikan. Baca selengkapnya di live updates untuk aplikasi Flutter.
Native Swift, .NET MAUI, Kotlin Multiplatform: tidak ada update native code
Stack ini menghasilkan native machine code. Mereka tidak bisa mengunduh pengganti native code. Aplikasi native tetap bisa mengunduh dan mengeksekusi code yang diinterpretasikan, seperti JavaScript lewat JavaScriptCore, selama memenuhi syarat Apple. Yang juga bisa dilakukan lewat over-the-air adalah mengubah data: remote config, feature flags untuk fitur yang sudah direview, server-driven UI, gambar, dan teks.
Unity dan game engine: konten bisa, code tidak
Game code dikompilasi. Asset bundles (level, art, data balancing) adalah konten dan bisa diunduh. Bahasa scripting yang disematkan seperti Lua adalah code yang diinterpretasikan dan mengikuti aturan yang sama dengan JavaScript.
Remote URL wrappers: live, tapi berisiko saat review
Aplikasi yang hanya memuat website Anda di dalam WebView akan dianggap "diperbarui" setiap kali Anda deploy situs tersebut. Masalahnya bukan pada guideline 2.5.2, melainkan guideline 4.2 (minimum functionality): Apple menolak aplikasi yang hanya berupa website di dalam frame. Menggabungkan web app dengan Capacitor, menambahkan fitur native, dan menggunakan live updates dapat menghindari hal ini.
Hal yang tidak bisa dilakukan stack apa pun di iOS
Apa pun framework Anda, live update tidak bisa:
- Download code native, framework, atau dynamic library
- Menambah permission atau entitlements baru
- Mengubah aplikasi menjadi sesuatu yang tidak dijelaskan di listing App Store
- Mengaktifkan fitur yang sebelumnya disembunyikan dari App Review
Ke mana selanjutnya
- Jawaban Android: Apakah Google mengizinkan live updates tanpa review Play Store?
- Detail penegakan aturan: Cara Apple menegakkan batasan update OTA
- Alur persetujuan: Capacitor update OTA: Panduan persetujuan App Store
- Cerita penolakan nyata: Kisah horor penolakan App Store
Rilis perbaikan hari ini, bukan setelah review
Live updates Capgo push perubahan JavaScript, HTML, dan CSS ke aplikasi Capacitor Anda dalam hitungan menit, dengan channels, rollback, delta updates, dan end-to-end encryption. Open source dan bisa di-self-host.
bunx @capgo/cli@latest init
Ikuti quickstart untuk mengirim update pertama Anda.