Short answer: An over-the-air (OTA) update for an iOS app is a change to the app's code or content delivered directly to installed devices from the developer's servers, without a new App Store submission. OTA updates are limited to interpreted code and assets under Apple's Developer Program License Agreement; native binary changes still go through App Review.
What is the difference between an OS OTA update and an app OTA update?
An OS OTA update replaces part of the operating system or the device firmware; an app OTA update changes one application's own code or content while the OS stays put. The general-purpose reference covers the first sense: Wikipedia defines an over-the-air update as "an update to an operating system, or to firmware for an embedded system, that is delivered through a wireless network" (Over-the-air update, Wikipedia, retrieved 22 August 2026). On iOS the OS sense is what Settings shows you. The app sense — the one iOS developers mean when they say "we hotfixed it OTA" — is the subject of this page: the developer's own servers hand an installed app new code, and the App Store is not involved.
Which kinds of app OTA update exist?
Six mechanisms travel under the OTA label. Three of them ship data the shipped binary already knows how to interpret; three ship code. The Apple basis column matters because only the code rows engage the interpreted-code clause.
| Kind of app OTA update | What changes | Stack | Apple basis |
|---|---|---|---|
| Remote config | Values the shipped code already reads | Any | Data, not code — outside §3.3.1(B) |
| Feature flags | Which already-shipped code path runs | Any | Data, not code — but Guideline 2.3.1 forbids concealed features |
| Server-driven UI | Layout assembled from components in the binary | Any | Data, not code |
| JavaScript bundle replacement | The app's JavaScript, styling and images | React Native (CodePush, Expo EAS Update) | Interpreted code under §3.3.1(B) |
| Dart patching | Dart code, not native code | Flutter (Shorebird) | Interpreted code under §3.3.1(B) |
| Native Swift via WebAssembly | Swift logic, async code and SwiftUI view bodies | Native Swift / SwiftUI (Patch) | Interpreted code under §3.3.1(B) |
The first three rows are limited by foresight at build time: you can flip only a flag you already wrapped, or restyle a component you already shipped. The last three rows ship new logic, which is why they carry the compliance conversation with them. Note that the stack column, not the vendor, decides what is available to a given app: a native Swift app has no JavaScript or Dart bundle for CodePush, Expo EAS Update or Shorebird to replace, and a React Native app has no Swift for Patch to compile. The three code rows are therefore alternatives to each other only in the sense that each is the OTA option for a different codebase.
What does Apple allow and forbid?
Apple forbids downloading executable code and allows downloading interpreted code under three conditions. Section 3.3.1(B) of the Apple Developer Program License Agreement, headed "Executable Code", reads:
"Except as set forth in the next paragraph, an Application may not download or install executable code. Interpreted code may be downloaded to an Application but only so long as such code: (a) does not change the primary purpose of the Application by providing features or functionality that are inconsistent with the intended and advertised purpose of the Application (b) does not bypass signing, sandbox, or other security features of the OS; and (c) for Applications distributed on the App Store, does not create a store or storefront for other Applications."
— Apple Developer Program License Agreement, §3.3.1(B) "Executable Code", retrieved 22 August 2026 from the Apple Developer agreements page. The clause was numbered §3.3.2 before the agreement was reorganised.
What does App Review Guideline 2.5.2 say?
Guideline 2.5.2 is the reviewer-facing statement of the same boundary, and it is written as a prohibition with a narrow educational exception:
"Apps should be self-contained in their bundles, and may not read or write data outside the designated container area, nor may they download, install, or execute code which introduces or changes features or functionality of the app, including other apps. Educational apps designed to teach, develop, or allow students to test executable code may, in limited circumstances, download code provided that such code is not used for other purposes. Such apps must make the source code provided by the app completely viewable and editable by the user."
— App Review Guideline 2.5.2, Software Requirements, retrieved 22 August 2026.
The two documents are read together: Guideline 2.5.2 is the default and DPLA §3.3.1(B) is the carve-out. A rejection citing "Guideline 2.5.2 — Performance — Software Requirements" is answered by explaining exactly what the mechanism downloads and what evaluates it. Longer treatment in what Apple allows for OTA updates.
Why did Apple crack down on hot-push SDKs in 2017?
Because the objection was to code that changes an app after review, not to interpreted code as such. In March 2017 Apple mailed developers whose apps embedded hot-push code SDKs; 9to5Mac's report of the enforcement named Rollout.io as the service in question. The notice read:
"Your app, extension, and/or linked framework appears to contain code designed explicitly with the capability to change your app's behavior or functionality after App Review approval, which is not in compliance with section 3.3.2 of the Apple Developer Program License Agreement and App Store Review Guideline 2.5.2. This code, combined with a remote resource, can facilitate significant changes to your app's behavior compared to when it was initially reviewed for the App Store."
— Apple's notice to developers, quoted by 9to5Mac, 7 March 2017. Section 3.3.2 is the clause now numbered §3.3.1(B).
The operative words are "change your app's behavior or functionality after App Review approval". Interpreted code that runs beside the reviewed logic, inside the sandbox, is what §3.3.1(B) permits. The enforcement record is traced in what Apple allows for OTA updates.
How does an OTA update reach a device?
Through an update check the app itself performs, usually at launch. The shape is the same across tools: the app asks the vendor's backend whether a newer module exists for its channel and its build, downloads it if so, verifies it, activates it, and falls back to the code in the signed binary if any step fails. In Patch, Patch.shared.start() activates the best module already cached before touching the network, so an offline launch runs the current over-the-air code, then checks in the background. The check reports the device's channel, app version, OS version and native-shell fingerprint, and the backend answers with a module only when the fingerprint matches and the device falls inside the rollout percentage. Step-by-step in how OTA updates work on iOS.
What is a channel?
A channel is a named update stream that a build subscribes to and receives releases from. A build configured for staging never receives a module pushed to production, so one codebase can run an internal beta and a public release at the same time. Channel names are arbitrary strings, which makes per-tester and per-tenant streams possible without new infrastructure. Channels segment who gets a release; they say nothing about whether the release is safe for a given build — that is the fingerprint's job, and the two gates are independent. Most teams run two or three: a production stream, a staging stream their internal builds subscribe to, and sometimes a beta stream for external testers. See the channels documentation and the glossary of OTA terms.
What is a staged rollout?
A staged rollout is a release served to a fixed percentage of eligible devices, raised over time as the failure rate holds. Patch derives each device's bucket by hashing its stable device id together with the release into a value from 0 to 99 and serves the release when that bucket is below the rollout percentage, so the assignment is deterministic: raising the percentage adds devices and never removes one. That is a different mechanism from Apple's own phased release, which distributes a new binary on a fixed seven-day schedule to users with automatic updates switched on. See the rollouts documentation.
What is a rollback?
A rollback is the act of making a previously active module active again, or of recalling the current one. In Patch, patchcli rollback re-activates the previous module on a channel; a device already running the rolled-back release with no active replacement is told to revert on its next check, deactivates the patch locally, and returns to the code in the signed binary. That recall has no App Store equivalent, because the store cannot take a binary back from a device that already installed it. The comparison of every rollback option is in how to roll back an iOS release instantly.
What is a compatibility fingerprint?
A compatibility fingerprint is a hash of the parts of an app that a patch cannot change, used to decide whether a given patch is safe for a given installed build. Patch hashes the native shell — native Swift files, Info.plist, entitlements, linked frameworks, deployment target, SDK version and compiler version — and records it with each release; devices report theirs on every check and are served only matching modules. Editing a view body that already ships over the air does not move it, because patchable bodies are subtracted from the hash per function; upgrading Xcode does move it, because the compiler version participates in the hash. A mismatch is not a bug report, it is the system refusing to ship a patch it cannot prove is compatible. The reasoning and the recovery steps are in the compatibility fingerprint documentation.
Can native Swift be updated over the air?
Yes, by compiling the changed Swift to WebAssembly and interpreting it on device. That is what Patch does: the build engine partitions the project into a WebAssembly module and a native shell, the patchcli CLI compiles the module with the swift.org toolchain and the WebAssembly Swift SDK, and the PatchSDK runs it in WasmKit, a WebAssembly interpreter written in Swift. Swift logic, async/await code and SwiftUI view bodies patch; code that calls OS APIs directly stays native, and a patch can never introduce a framework or entitlement the signed binary lacks. Details in can you hotfix a Swift app over the air and the docs on what Patch can and cannot update.
What happened to CodePush?
The hosted service that ran CodePush shut down. Microsoft's retirement notice states: "Visual Studio App Center is scheduled for retirement on March 31, 2025. After that date, it will not be possible to sign in with your user account nor make API calls." For CodePush specifically, Microsoft writes: "We have prepared a special version of CodePush that can be integrated into your app and run independently from App Center", pointing at the microsoft/code-push-server repository (Visual Studio App Center Retirement, Microsoft Learn, retrieved 22 August 2026). React Native teams largely moved to Expo EAS Update. The landscape after the shutdown is mapped in the 2026 OTA tool map and on the tools compared page.
Frequently asked questions
Is an OTA update the same as an App Store update?
No. An App Store update replaces the signed binary and passes through App Review; an OTA update delivers interpreted code or data to the app already installed, and the signed binary is unchanged. The two are complementary: OTA carries corrections between releases, and the App Store carries anything that needs new native code, frameworks or entitlements.
Does an OTA update need App Store review?
No, provided it stays inside Apple's interpreted-code clause. DPLA §3.3.1(B) permits downloaded interpreted code that does not change the app's primary purpose, does not bypass signing or sandbox protections, and does not create a storefront for other applications. Anything outside those conditions, or anything requiring native code, needs a submission.
Can an OTA update change native iOS code?
No. Compiled native code inside the signed binary cannot be rewritten by a downloaded patch, and no OTA tool on iOS claims otherwise; Shorebird's FAQ states plainly that it "does not support changing native code (e.g. Java/Kotlin on Android or Objective-C/Swift on iOS)". Patch ships changed Swift as interpreted WebAssembly rather than by modifying the binary.
What is the difference between a hot update and an OTA update?
They are the same thing under two names. "Hot update", "hot push" and "hot patch" are the older vocabulary, and Apple's 2017 enforcement notices attached to SDKs marketed with those words. "OTA update" is the term the current tools use. The mechanism that matters is what the downloaded payload is allowed to touch, not the label.
Do OTA updates work offline?
The already-downloaded module does. An app keeps running whichever module it activated last, so an offline launch is unaffected and a failed update check leaves the active module in place. Receiving a new module requires a network connection, and the app picks it up on the next successful check.