Skip to main content

Hooks

SwiftPatch provides three React hooks for managing OTA updates. Pick the one that fits your use case.

HookUse when you need...
useSwiftPatchFull control -- state + actions
useSwiftPatchUpdateRead-only update status
useSwiftPatchModalBuilt-in update modal

useSwiftPatch

The primary hook. Returns update state and all actions.

import { useSwiftPatch, UpdateStatus } from '@swiftpatch/react-native';

function UpdateScreen() {
const {
// State
status,
downloadProgress,
currentBundle,
availableUpdate,
isRestartRequired,
error,
lastCheckedAt,

// Actions
checkForUpdate,
downloadUpdate,
installUpdate,
restart,
rollback,
clearPendingUpdate,
getCurrentBundle,
markMounted,
} = useSwiftPatch();

const handleUpdate = async () => {
const update = await checkForUpdate();
if (update) {
await downloadUpdate();
await installUpdate();
restart();
}
};

return (
<View>
{currentBundle && (
<Text>Current: {currentBundle.hash.slice(0, 16)}</Text>
)}
{status === UpdateStatus.DOWNLOADING && (
<Text>Downloading: {downloadProgress?.percentage}%</Text>
)}
{isRestartRequired && (
<Text>Restart required to apply update</Text>
)}
<Button title="Check for Updates" onPress={handleUpdate} />
</View>
);
}

State

PropertyTypeDescription
statusUpdateStatuschecking, upToDate, updateAvailable, downloading, readyToInstall, installing, restartRequired, error
downloadProgressDownloadProgress | nulldownloadedBytes, totalBytes, percentage
currentBundleBundleInfo | nullRunning bundle info (hash, version, etc.)
availableUpdateReleaseInfo | nullAvailable update (after checkForUpdate())
isRestartRequiredbooleanWhether a restart is needed
errorSwiftPatchError | nullLast error (when status is error)
lastCheckedAtDate | nullTimestamp of last check

Actions

MethodReturn TypeDescription
checkForUpdate()Promise<ReleaseInfo | null>Check for updates
downloadUpdate()Promise<void>Download the available update
installUpdate()Promise<void>Install the downloaded update
restart()voidRestart to apply the update
rollback()Promise<void>Roll back to the previous version
clearPendingUpdate()Promise<void>Clear a pending update
getCurrentBundle()Promise<BundleInfo | null>Refresh current bundle info
markMounted()voidMark app as mounted (for crash detection)

useSwiftPatchUpdate

A lightweight, read-only hook for update status. Use this when you only need to display state, not trigger actions.

import { useSwiftPatchUpdate } from '@swiftpatch/react-native';

function UpdateBadge() {
const {
isRestartRequired,
newReleaseBundle,
currentBundle,
status,
restart,
} = useSwiftPatchUpdate();

if (isRestartRequired) {
return (
<TouchableOpacity onPress={restart}>
<Text>Update ready — tap to restart</Text>
</TouchableOpacity>
);
}

return null;
}

Return Value

PropertyTypeDescription
isRestartRequiredbooleanWhether a restart is needed
newReleaseBundleReleaseInfo | nullAvailable update (if any)
currentBundleBundleInfo | nullCurrently installed bundle
statusUpdateStatusCurrent update status
restart() => voidRestart the app

useSwiftPatchModal

Controls the built-in update modal from withSwiftPatch. The modal handles checking, downloading with progress, and prompting for restart.

import { useSwiftPatchModal } from '@swiftpatch/react-native';

function MyComponent() {
const { showModal, hideModal, isModalVisible } = useSwiftPatchModal();

return (
<Button title="Check for Updates" onPress={showModal} />
);
}

Return Value

PropertyTypeDescription
showModal() => voidShow the update modal
hideModal() => voidHide the update modal
isModalVisiblebooleanWhether the modal is visible
info

The modal requires sdkPin in your SDK config. Without it, the modal won't render.


Examples

Update Banner

import { useSwiftPatch } from '@swiftpatch/react-native';

function UpdateBanner() {
const { isRestartRequired, restart } = useSwiftPatch();

if (!isRestartRequired) return null;

return (
<TouchableOpacity onPress={restart}>
<Text>Update ready. Tap to restart.</Text>
</TouchableOpacity>
);
}

Settings Screen with Update Check

import { useSwiftPatch, useSwiftPatchModal } from '@swiftpatch/react-native';

function SettingsScreen() {
const { currentBundle } = useSwiftPatch();
const { showModal } = useSwiftPatchModal();

return (
<View>
<Text>
Bundle: {currentBundle?.hash?.slice(0, 16) || 'Original'}
</Text>
<Button title="Check for Updates" onPress={showModal} />
</View>
);
}

Mandatory Update Gate

import { useSwiftPatch } from '@swiftpatch/react-native';

function MandatoryUpdateGate({ children }) {
const { isRestartRequired, restart } = useSwiftPatch();

if (isRestartRequired) {
return (
<View style={styles.fullScreen}>
<Text style={styles.title}>Update Required</Text>
<Text>A required update has been downloaded.</Text>
<Button title="Restart Now" onPress={restart} />
</View>
);
}

return children;
}

Download Progress

import { useSwiftPatch, UpdateStatus } from '@swiftpatch/react-native';

function DownloadProgress() {
const { status, downloadProgress } = useSwiftPatch();

if (status === UpdateStatus.DOWNLOADING && downloadProgress) {
return (
<View>
<Text>Downloading update...</Text>
<ProgressBar progress={downloadProgress.percentage / 100} />
<Text>
{downloadProgress.downloadedBytes} / {downloadProgress.totalBytes} bytes
</Text>
</View>
);
}

return null;
}