Skip to main content

Android Setup

The automatic way is one command. The manual way is a short snippet you paste into MainApplication. Both are documented here.

The automatic path​

npx swiftpatch init

That's it. Move on to wrapping your app.

Under the hood, swiftpatch init modifies two Android files. Every change is bounded by // swiftpatch-begin / // swiftpatch-end markers, so swiftpatch unlink reverses them cleanly.

MainApplication.kt (Kotlin — RN 0.73+)​

android/app/src/main/java/.../MainApplication.kt
import com.swiftpatch.SwiftPatchModule

class MainApplication : Application(), ReactApplication {
override val reactNativeHost: ReactNativeHost =
object : DefaultReactNativeHost(this) {
// ... your existing packages, dev support, etc.

// swiftpatch-begin (auto-generated, do not edit between markers)
override fun getJSBundleFile(): String? {
return SwiftPatchModule.getJSBundleFile(applicationContext)
?: super.getJSBundleFile()
}
// swiftpatch-end
}
}

For RN 0.82+ projects using ReactHost:

override val reactHost: ReactHost by lazy {
getDefaultReactHost(
context = applicationContext,
packageList = PackageList(this).packages,
// swiftpatch-begin (auto-generated, do not edit between markers)
jsBundleFilePath = SwiftPatchModule.getJSBundleFile(applicationContext),
// swiftpatch-end
)
}

The SDK's override calls super.getJSBundleFile() if no OTA bundle is available. This is critical — if Swiftpatch has nothing to serve, the default store bundle loader runs unchanged.

MainApplication.java (legacy)​

android/app/src/main/java/.../MainApplication.java
import com.swiftpatch.SwiftPatchModule;

public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new DefaultReactNativeHost(this) {
// ... your existing overrides

// swiftpatch-begin (auto-generated, do not edit between markers)
@Override
protected String getJSBundleFile() {
String path = SwiftPatchModule.getJSBundleFile(getApplicationContext());
if (path != null) return path;
return super.getJSBundleFile();
}
// swiftpatch-end
};
}

strings.xml​

android/app/src/main/res/values/strings.xml
<resources>
<string name="app_name">YourApp</string>

<!-- swiftpatch-begin (auto-generated, do not edit between markers) -->
<string name="swiftpatch_deployment_key">dep_xxx...</string>
<!-- swiftpatch-end -->
</resources>
Key casing

Android uses the snake-case form swiftpatch_deployment_key. iOS uses the PascalCase form SwiftPatchDeploymentKey. The SDK reads from both.

Manual setup​

If auto-patching can't run, use --manual:

npx swiftpatch init --manual

The CLI prints the snippets. Steps to apply by hand:

1. Paste the getJSBundleFile override​

From the Kotlin / Java example above.

2. Add the deployment key to strings.xml​

<string name="swiftpatch_deployment_key">dep_xxx...</string>

3. (Optional) Wire silent-push-triggered sync​

If you want FCM data messages to trigger background update checks:

override fun onMessageReceived(message: RemoteMessage) {
if (message.data["swiftpatch_event"] != null) {
SilentPushReceiver.handleData(this, message.data)
return
}
// ... your existing handler
}

See Background sync.

Minimum Android version​

API 24 (Android 7.0) or higher. WorkManager (used for scheduled background sync) requires 14+, which is always true on API 24. Modern React Native templates default to API 24.

ProGuard / R8​

The SDK ships its own consumer ProGuard rules. No manual setup required.

If you've heavily customized your proguard-rules.pro, ensure the following packages are not obfuscated:

-keep class com.swiftpatch.** { *; }
-keepnames class com.swiftpatch.**

New Architecture​

Fully supported. Set newArchEnabled=true in android/gradle.properties. See New Architecture.

Troubleshooting​

  • "Cannot resolve symbol SwiftPatchModule" — autolinking didn't pick up the package. Run cd android && ./gradlew clean and rebuild.
  • App loads the old bundle after update — the getJSBundleFile() override is missing or misplaced. Run swiftpatch doctor to verify.
  • WorkManager crash on boot — you're on a very old minSdkVersion. Raise to 24.

For more, see Troubleshooting.

Next steps​