SDK Usage Guide
Automatic Updates
The simplest approach. Updates are checked and installed automatically:
import { initNorrix } from '@norrix/client-sdk';
initNorrix({
updateUrl: 'https://norrix.net',
checkForUpdatesOnLaunch: true,
installUpdatesAutomatically: true,
});With this configuration:
- App launches and checks for updates
- If compatible update available, it’s downloaded
- Update is installed silently
- Update activates on next app restart
With Restart Prompt
Prompt users to restart after an update:
initNorrix({
updateUrl: 'https://norrix.net',
checkForUpdatesOnLaunch: true,
installUpdatesAutomatically: true,
promptToRestartAfterInstall: true, // Shows restart dialog
});Manual Update Control
For full control over the update flow:
import { initNorrix } from '@norrix/client-sdk';
// Initialize without auto-install
const norrix = initNorrix({
updateUrl: 'https://norrix.net',
});
// Check for updates manually
async function checkAndApplyUpdate() {
const update = await norrix.checkForUpdates();
if (!update.updateAvailable) {
console.log('App is up to date');
return;
}
if (update.requiresStoreUpdate) {
// Native changes detected - direct user to app store
showStoreUpdatePrompt(update.compatibilityReason);
return;
}
// Show update prompt to user
const shouldUpdate = await showUpdateDialog({
version: update.version,
releaseNotes: update.releaseNotes,
});
if (!shouldUpdate) {
return; // User declined
}
// Download the update
const success = await norrix.downloadUpdate(update);
if (success) {
// Apply the update
norrix.applyUpdate();
}
}Status Monitoring
Track update progress with callbacks:
import { initNorrix, SyncStatus } from '@norrix/client-sdk';
initNorrix({
updateUrl: 'https://norrix.net',
checkForUpdatesOnLaunch: true,
installUpdatesAutomatically: true,
statusCallback: (status, data) => {
switch (status) {
case SyncStatus.CHECKING_FOR_UPDATE:
showSpinner('Checking for updates...');
break;
case SyncStatus.DOWNLOADING_PACKAGE:
showSpinner('Downloading update...');
break;
case SyncStatus.INSTALLING_UPDATE:
showSpinner('Installing update...');
break;
case SyncStatus.UPDATE_INSTALLED:
hideSpinner();
showToast(`Update ${data?.version} ready!`);
break;
case SyncStatus.UP_TO_DATE:
hideSpinner();
break;
case SyncStatus.ERROR:
hideSpinner();
showError(data?.message);
break;
}
},
downloadProgressCallback: (progress) => {
updateProgressBar(progress);
},
});What Can Be Updated
✅ OTA-Compatible Changes
These changes can be pushed via OTA:
- JavaScript/TypeScript code: Business logic, API calls, utilities
- CSS/SCSS styles: Colors, layouts, animations
- Assets: Images, fonts, icons (in
/srcor/app) - Non-native npm packages: Pure JS/TS packages
❌ Requires Store Build
These changes require a new store binary:
- NativeScript platform versions:
@nativescript/ios,@nativescript/android - Native plugin updates: Plugins with native code
- App_Resources changes: Icons, splash screens, Info.plist
- Custom native code: NativeSource files
Reset OTA Updates
To reset all OTA updates and return to the original store binary:
const norrix = initNorrix({
updateUrl: 'https://norrix.net',
});
// Clear all OTA updates
norrix.resetAllOTAs();This:
- Clears stored OTA fingerprint and version
- Removes downloaded OTA packages
- Prompts user to restart
- App restarts with original store binary
Use Cases
- Debugging OTA issues
- Reverting problematic updates
- Developer testing
Fingerprint Access
Get the current native binary fingerprint:
const norrix = initNorrix({
updateUrl: 'https://norrix.net',
});
const hash = norrix.getCurrentFingerprintHash();
console.log('Binary fingerprint:', hash);This returns the fingerprint hash from:
- Cached value in ApplicationSettings (if previously read)
assets/norrix.fingerprint.jsonbundled in the app
The fingerprint is cached to ensure consistency even when running from OTA bundles.
Force Close App
Utility to close the app (useful for manual restart handling):
norrix.closeAppNow();This calls:
- iOS:
exit(0) - Android:
java.lang.System.exit(0)
Use with caution. Only call after user confirmation.
HMR Compatibility
When Hot Module Replacement (HMR) is enabled during development, the SDK skips OTA checks to avoid conflicts:
statusCallback: (status) => {
if (status === SyncStatus.SKIPPING_BECAUSE_HMR_ENABLED) {
console.log('OTA skipped - HMR is active');
}
};This is automatic. No configuration needed.
Error Handling
Handle update errors gracefully:
initNorrix({
updateUrl: 'https://norrix.net',
checkForUpdatesOnLaunch: true,
installUpdatesAutomatically: true,
statusCallback: (status, data) => {
if (status === SyncStatus.ERROR) {
// Log error for debugging
console.error('OTA Error:', data?.message);
// Optionally notify error tracking
Sentry.captureException(new Error(data?.message));
// App continues normally - OTA is non-blocking
}
},
});OTA errors are non-fatal. The app continues with its current version.