Short answer: Yes. A hotfix to Swift logic, async/await code or a SwiftUI view can ship over the air to installed apps: Patch compiles the changed Swift to WebAssembly and the PatchSDK runs it in WasmKit, falling back to the signed binary if the patch cannot run. Code that calls OS APIs directly, and any new framework or entitlement, still needs a binary release.
What is a hotfix versus a release?
A hotfix is a narrow, urgent correction to code that is already in users' hands; a release is the planned shipment of everything a team has built since the last one. On iOS the two normally travel the same road: build, submit, wait for App Review, then wait again for devices to install. Apple states that "On average, 90% of submissions are reviewed in less than 24 hours", but review is only one segment of that road, and the installation tail is the segment nobody controls. An over-the-air layer separates the two: the hotfix goes out on its own, and the next binary release carries it plus everything else. The full menu of urgent options is in the iOS hotfix playbook.
What kinds of Swift bugs can be fixed over the air?
The fixable set is the code that does not talk directly to an OS framework: pure logic, validation rules, parsing and formatting, business rules, an async flow, and the body of a SwiftUI view. A one-line arithmetic bug is the archetype — the kind of mistake that ships because it reads correctly.
// before — discount applied after tax
let total = (subtotal * (1 + taxRate)) - discount
// after — discount applied before tax
let total = (subtotal - discount) * (1 + taxRate)That function is pure arithmetic on value types, so the engine compiles it to WebAssembly and the fix ships without a resubmission. The same is true of a wrong validation predicate, a date that formats in the wrong locale, a JSON field decoded under the wrong key, or a SwiftUI view that puts the button below the fold.
What can't be fixed over the air?
An OTA patch can never introduce a native symbol, framework, or entitlement that is not already compiled and signed into the shipped app. That is the binary-symbol wall, and it is physics rather than backlog: the operating system reads the signed Info.plist and entitlements at launch, and WebAssembly cannot synthesise a permission key or link a framework the binary never linked. The second face of the same wall is compiled native code: functions the engine classified as native cannot be rewritten by a patch. Changing them moves the native-shell fingerprint, and Patch refuses the release rather than shipping something it cannot prove is compatible. The exhaustive map is in the docs on what Patch can and cannot update.
How does Patch decide what is patchable?
The decision is made at build time, function by function, and it errs toward native. The engine sorts each function into one of four buckets: WebAssembly for pure logic; bridged for code that touches only APIs Patch has a host bridge for, such as networking, UserDefaults, keychain or notifications; split for mixed functions, whose safe half is lifted over the air while the rest stays in the shell; and native for anything touching a must-stay-native API. When a generated module fails to compile, the offending code is demoted to native and the build retries, so a broken module is never produced. SwiftUI views need no wrapper: patchcli prepare marks each body patchable and generates a dynamic-replacement thunk, the mechanism Xcode Previews already uses.
How fast does a fix reach devices?
A fix reaches a device on that device's next update check, which the SDK performs at launch. There is no push wake-up and no forced restart: Patch.shared.start() activates the best module already cached, then checks the backend in the background and applies whatever it finds. Which means fleet-wide adoption tracks how often people open the app, and no OTA vendor — Patch included — can quote a number for that, because it belongs to your users rather than to the tool. What the OTA layer removes is the review and installation segment: the build step is the developer's own compile, and after that the release is available to the next check.
How do I verify the fix landed?
Ask the deployment, not the crash reports. patchcli status reports the active version on a channel, the rollout percentage, downloads, activations, adoption and the failure rate.
patchcli status --channel productionAdoption is activations over downloads; the failure rate is errors over activations plus errors, and the CLI hints at a rollback when failures climb past 2%. The console shows the same release from the other side, including targeted percentage against received percentage. Device check-ins arrive before any release exists, so the Usage page shows connected devices from the first launch of an instrumented build. Channel-by-channel detail is in the channels documentation and the rollouts documentation.
What if the hotfix is wrong?
Roll it back, which takes one command and no review.
patchcli rollback --channel productionThe previous module re-activates and propagates on each device's next update check. A device already running the rolled-back release, with no active replacement, is told to revert: the SDK deactivates the patch locally and the app falls back to the code in the signed binary. That recall is the property a binary release cannot offer, because the App Store has no mechanism to take a version back from a device that already installed it. Staging limits the blast radius before you need any of this — release at --rollout 10, watch, widen. The runbook is in how to roll back an iOS release instantly.
Can a hotfix break the app?
The design goal is that a failed patch degrades to the app you shipped. Four gates stand between a bad build and a broken launch. At build time, code the engine cannot prove safe is demoted to native, and a module that fails to compile is never produced. At release time, the native-shell fingerprint gate refuses a patch built against a different binary. On device, a missing, corrupt or non-activating module leaves the previous module in place and the app runs the native fallback baked into the binary. And at the view level, a SwiftUI body the renderer cannot reconstitute renders natively instead. None of that makes a logically wrong patch correct — a bad fix is still a bad fix, which is what staged rollouts and rollback are for.
Is this the same as CodePush, EAS Update or Shorebird?
No — those tools patch a bundle, not Swift. CodePush replaced React Native JavaScript bundles, and the hosted App Center service that ran it retired on 31 March 2025. Expo EAS Update is the React Native successor and serves a project's "own non-native pieces (such as JS, styling, and images)". Shorebird patches Dart for Flutter, and its FAQ says plainly that Shorebird "does not support changing native code (e.g. Java/Kotlin on Android or Objective-C/Swift on iOS)". A native Swift app has no JavaScript or Dart bundle for any of them to replace. Patch compiles the changed Swift itself. The three-way comparison is on the OTA update tools compared page, with per-vendor detail on the CodePush, Expo EAS Update and Shorebird pages.
Frequently asked questions
Can you hotfix a SwiftUI view without a wrapper?
Yes. patchcli prepare marks each var body: some View patchable and generates a dynamic-replacement thunk beside it, so no view is wrapped in a PatchView and no view source changes. Prepare runs automatically inside every build, push and release, so views added later are picked up with no extra step.
Does a hotfix survive an app update from the App Store?
No, and that is deliberate. A new App Store build has a different native shell, so its fingerprint differs and the old patch is no longer served to it. Ship the fixed source in the new binary, then register that build's fingerprint with patchcli fingerprint register before releasing further patches against it.
Can a hotfix add a new screen?
Yes, within the binary-symbol wall. SwiftUI structure is authorable over the air, so a patch can add views, navigation destinations and sheets built from components the signed binary already links. It cannot add a screen that needs a framework the app never linked or an entitlement the app never declared, and it must not change the app's primary purpose.
Is an over-the-air hotfix allowed by Apple?
Yes, conditionally. Apple's Developer Program License Agreement §3.3.1(B) permits downloaded interpreted code provided it does not change the app's primary purpose, does not bypass signing or sandbox protections, and does not create a storefront for other applications. A bug fix to your own app is squarely inside those conditions; compliance remains the developer's responsibility.
What happens to a patch when the device is offline?
The app keeps running the module it already cached. The SDK activates the best cached module before doing any network work, so an offline launch is unaffected, and a failed update check leaves the active module untouched. The next successful check picks up whatever the channel is serving.