UNPKG

native-update

Version:

Foundation package for building a comprehensive update system for Capacitor apps. Provides architecture and interfaces but requires backend implementation.

394 lines (317 loc) 9.46 kB
# Advanced Scenarios This guide covers complex use cases and advanced patterns for the Capacitor Native Update plugin. ## Delta Updates Minimize download sizes by only downloading changed files: ```typescript import { NativeUpdate } from 'native-update'; async function checkForDeltaUpdate() { const currentManifest = await NativeUpdate.current(); const result = await NativeUpdate.sync({ installMode: 'ON_NEXT_RESTART' }); if (result.updateAvailable && result.deltaAvailable) { console.log(`Delta update available: ${result.deltaSize} bytes`); await downloadDeltaUpdate(result.deltaUrl); } } async function downloadDeltaUpdate(deltaUrl: string) { // Download requires url, version, and checksum parameters const download = await NativeUpdate.download({ url: result.deltaUrl, version: result.version, checksum: result.checksum }); // Set the bundle as active await NativeUpdate.set({ bundleId: download.bundleId, version: download.version, checksum: download.checksum }); } ``` ## Update Channels Manage different release tracks: ```typescript // Configure update channels enum UpdateChannel { PRODUCTION = 'production', BETA = 'beta', DEVELOPMENT = 'development' } async function setupUpdateChannel(channel: UpdateChannel) { await NativeUpdate.configure({ updateChannel: channel, updateUrl: `https://updates.example.com/api/${channel}/check` }); } // Switch channels based on user preference async function switchToBetaChannel() { await setupUpdateChannel(UpdateChannel.BETA); // Check for updates in the new channel const result = await NativeUpdate.sync(); if (result.updateAvailable) { console.log(`Beta update ${result.version} available`); } } ``` ## Staged Rollouts Implement gradual update deployment: ```typescript async function checkStagedUpdate() { const deviceId = await getDeviceId(); const rolloutPercentage = hashDeviceId(deviceId) % 100; const result = await NativeUpdate.sync({ installMode: 'ON_NEXT_RESTART' }); if (result.updateAvailable && result.rolloutPercentage >= rolloutPercentage) { // Device is eligible for update await downloadAndInstall(result); } } ``` ## Background Updates Download updates in the background without interrupting users: ```typescript async function setupBackgroundUpdates() { // Configure background update behavior await NativeUpdate.configure({ backgroundUpdateMode: 'wifi-only', autoInstallMode: 'on-restart' }); // Configure automatic update checks await NativeUpdate.configure({ checkInterval: 14400, // 4 hours in seconds autoCheck: true }); } // Handle background update events NativeUpdate.addListener('backgroundUpdateNotification', (event) => { // Notify user that update is ready if (event.updateAvailable) { showUpdateNotification({ version: event.version, type: event.type }); } }); ``` ## Rollback Strategies Implement automatic rollback on update failures: ```typescript async function safeUpdate() { // Get current version info before update const backup = await NativeUpdate.current(); try { // Attempt update await NativeUpdate.set({ bundleId: 'new-update-id', version: 'new-version', checksum: 'bundle-checksum' }); // Verify update success const health = await performHealthCheck(); if (!health.passed) { throw new Error('Health check failed'); } // Notify app is ready with new bundle await NativeUpdate.notifyAppReady(); } catch (error) { console.error('Update failed, rolling back:', error); // Automatic rollback await NativeUpdate.reset(); // Report failure to analytics reportUpdateFailure(error); } } async function performHealthCheck(): Promise<{ passed: boolean }> { // Custom health check logic try { // Test critical functionality await testApiConnection(); await testDatabaseAccess(); await testUIComponents(); return { passed: true }; } catch { return { passed: false }; } } ``` ## Multi-Bundle Management Handle multiple update bundles for A/B testing: ```typescript interface ABTestConfig { testId: string; variants: { control: string; treatment: string; }; } async function setupABTest(config: ABTestConfig) { const variant = await determineVariant(config.testId); // Download appropriate bundle const bundleUrl = variant === 'treatment' ? config.variants.treatment : config.variants.control; const download = await NativeUpdate.download({ url: bundleUrl, version: variant, checksum: 'bundle-checksum' // This should come from server }); // Set the bundle as active await NativeUpdate.set({ bundleId: download.bundleId, version: download.version, checksum: download.checksum }); } ``` ## Custom Update UI Create sophisticated update experiences: ```typescript class UpdateManager { private updateState: UpdateState = { status: 'idle' }; async checkAndPromptUpdate() { // Check for update const result = await NativeUpdate.sync(); if (!result.updateAvailable) return; // Show custom update dialog const userChoice = await this.showUpdateDialog({ version: result.version, releaseNotes: result.releaseNotes, size: result.size, criticalUpdate: result.priority === 'critical' }); if (userChoice === 'update') { await this.performUpdate(result); } else if (userChoice === 'remind') { await this.scheduleReminder(); } } private async performUpdate(updateInfo: UpdateInfo) { this.updateState = { status: 'downloading', progress: 0 }; // Download with progress tracking const downloadListener = NativeUpdate.addListener( 'downloadProgress', (progress) => { this.updateState = { status: 'downloading', progress: progress.percent }; this.updateUI(); } ); try { // Download requires url, version, and checksum const download = await NativeUpdate.download({ url: updateInfo.url, version: updateInfo.version, checksum: updateInfo.checksum }); this.updateState = { status: 'installing' }; this.updateUI(); await NativeUpdate.set({ bundleId: download.bundleId, version: download.version, checksum: download.checksum }); this.updateState = { status: 'ready' }; await this.promptRestart(); } finally { downloadListener.remove(); } } } ``` ## Security-Enhanced Updates Implement advanced security measures: ```typescript async function secureUpdateCheck() { // Generate request signature const timestamp = Date.now(); const nonce = generateNonce(); const signature = await signRequest({ timestamp, nonce, version: getCurrentVersion() }); const result = await NativeUpdate.sync(); // Verify response signature if (!await verifyUpdateSignature(result)) { throw new Error('Invalid update signature'); } return result; } async function downloadWithIntegrityCheck(url: string, expectedHash: string) { const download = await NativeUpdate.download({ url: url, version: 'secure-version', checksum: expectedHash }); // Additional verification const verified = await NativeUpdate.validateUpdate({ bundlePath: download.path, checksum: download.checksum, signature: 'bundle-signature' }); if (!verified.isValid) { throw new Error('Bundle verification failed'); } return download; } ``` ## Performance Monitoring Track update performance and success rates: ```typescript class UpdateMetrics { async trackUpdateCycle() { const startTime = Date.now(); const metrics: UpdateMetrics = { checkStarted: startTime, downloadStarted: 0, downloadCompleted: 0, installStarted: 0, installCompleted: 0, errors: [] }; try { // Check phase const result = await NativeUpdate.sync(); if (!result.updateAvailable) { metrics.checkCompleted = Date.now(); await this.reportMetrics(metrics); return; } // Download phase metrics.downloadStarted = Date.now(); const download = await NativeUpdate.download({ url: result.url, version: result.version, checksum: result.checksum }); metrics.downloadCompleted = Date.now(); metrics.downloadSize = download.size; // Install phase metrics.installStarted = Date.now(); await NativeUpdate.set({ bundleId: download.bundleId, version: download.version, checksum: download.checksum }); metrics.installCompleted = Date.now(); metrics.success = true; } catch (error) { metrics.errors.push({ phase: this.getCurrentPhase(metrics), error: error.message, timestamp: Date.now() }); metrics.success = false; } await this.reportMetrics(metrics); } } ``` ## Next Steps - Review [Basic Usage](./basic-usage.md) for framework-specific implementations - See the [API Reference](../api/live-update-api.md) for detailed method documentation - Check [Basic Usage](./basic-usage.md) for simpler examples