UNPKG

native-update

Version:

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

393 lines (319 loc) 11.9 kB
# Background Update Feature The Background Update feature allows your app to check for updates automatically while running in the background, providing a seamless user experience with native notifications. ## Features ### Core Functionality - **Background Update Checking**: Automatically check for app and live updates while the app is not active - **Native Notifications**: Send native device notifications when updates are available - **Configurable Intervals**: Set custom check intervals and update types - **Battery Optimization**: Respect system battery saving modes and constraints - **Cross-Platform**: Works on iOS (BGTaskScheduler) and Android (WorkManager) ### Platform-Specific Implementation - **iOS**: Uses BGTaskScheduler for background tasks and UNUserNotificationCenter for notifications - **Android**: Uses WorkManager for background processing and NotificationManager for notifications - **Web**: Uses Notification API and intervals for fallback functionality ## Configuration ### Basic Setup ```typescript import { NativeUpdate, BackgroundUpdateType, } from 'native-update'; // Configure the plugin with background updates await NativeUpdate.configure({ backgroundUpdate: { enabled: true, checkInterval: 24 * 60 * 60 * 1000, // 24 hours updateTypes: [BackgroundUpdateType.BOTH], autoInstall: false, respectBatteryOptimization: true, requireWifi: false, notificationPreferences: { title: 'App Update Available', description: 'A new version is ready to install', soundEnabled: true, vibrationEnabled: true, showActions: true, actionLabels: { updateNow: 'Update Now', updateLater: 'Later', dismiss: 'Not Now', }, }, }, }); ``` ### Advanced Configuration ```typescript // Advanced background update configuration await NativeUpdate.configure({ backgroundUpdate: { enabled: true, checkInterval: 12 * 60 * 60 * 1000, // 12 hours updateTypes: [ BackgroundUpdateType.APP_UPDATE, BackgroundUpdateType.LIVE_UPDATE, ], autoInstall: true, // Only for live updates respectBatteryOptimization: true, allowMeteredConnection: false, minimumBatteryLevel: 20, requireWifi: true, maxRetries: 3, retryDelay: 5000, notificationPreferences: { title: 'MyApp Update', description: 'New features and improvements are available', iconName: 'update_icon', soundEnabled: true, vibrationEnabled: true, showActions: true, channelId: 'app_updates', channelName: 'App Updates', priority: 'high', actionLabels: { updateNow: 'Install Now', updateLater: 'Remind Me Later', dismiss: 'Skip This Version', }, }, }, }); ``` ## API Methods ### Enable Background Updates ```typescript await NativeUpdate.enableBackgroundUpdates({ enabled: true, checkInterval: 24 * 60 * 60 * 1000, updateTypes: [BackgroundUpdateType.BOTH], }); ``` ### Disable Background Updates ```typescript await NativeUpdate.disableBackgroundUpdates(); ``` ### Get Background Update Status ```typescript const status = await NativeUpdate.getBackgroundUpdateStatus(); console.log('Background updates enabled:', status.enabled); console.log('Last check:', new Date(status.lastCheckTime)); console.log('Next check:', new Date(status.nextCheckTime)); ``` ### Trigger Manual Check ```typescript const result = await NativeUpdate.triggerBackgroundCheck(); if (result.updatesFound) { console.log('Updates found!', result.appUpdate, result.liveUpdate); } ``` ### Configure Notifications ```typescript // Set notification preferences await NativeUpdate.setNotificationPreferences({ title: 'Custom Update Title', description: 'Custom update message', soundEnabled: true, vibrationEnabled: true, showActions: true, actionLabels: { updateNow: 'Install', updateLater: 'Later', dismiss: 'Skip', }, }); // Request notification permissions const granted = await NativeUpdate.requestNotificationPermissions(); if (granted) { console.log('Notification permissions granted'); } // Check permission status const permissions = await NativeUpdate.getNotificationPermissions(); console.log('Permissions granted:', permissions.granted); ``` ## Event Listeners ### Background Update Progress ```typescript NativeUpdate.addListener('backgroundUpdateProgress', (event) => { console.log('Background update progress:', event.status, event.percent); }); ``` ### Background Update Notifications ```typescript NativeUpdate.addListener('backgroundUpdateNotification', (event) => { console.log('Notification action:', event.action); switch (event.action) { case 'tapped': // User tapped notification break; case 'update_now': // User chose to update now break; case 'update_later': // User chose to update later break; case 'dismiss': // User dismissed notification break; } }); ``` ## Platform-Specific Setup ### iOS Setup Add to your `Info.plist`: ```xml <key>UIBackgroundModes</key> <array> <string>background-app-refresh</string> <string>background-processing</string> </array> <key>BGTaskSchedulerPermittedIdentifiers</key> <array> <string>com.aoneahsan.nativeupdate.background</string> </array> ``` ### Android Setup Add to your `AndroidManifest.xml`: ```xml <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> ``` ## Best Practices ### Battery Optimization - Set `respectBatteryOptimization: true` to work within system constraints - Use reasonable check intervals (not less than 15 minutes) - Consider `requireWifi: true` for large updates ### User Experience - Always request notification permissions before enabling background updates - Provide clear notification messages and actions - Handle notification actions appropriately - Allow users to disable background updates in settings ### Performance - Use `BackgroundUpdateType.APP_UPDATE` for critical updates only - Use `BackgroundUpdateType.LIVE_UPDATE` for content updates - Use `BackgroundUpdateType.BOTH` sparingly to avoid excessive battery usage ## Error Handling ```typescript try { await NativeUpdate.enableBackgroundUpdates(config); } catch (error) { console.error('Failed to enable background updates:', error); } // Listen for background update errors NativeUpdate.addListener('backgroundUpdateProgress', (event) => { if (event.status === 'failed' && event.error) { console.error('Background update failed:', event.error); } }); ``` ## Configuration Options ### BackgroundUpdateConfig | Option | Type | Default | Description | | ---------------------------- | ---------------------- | ---------- | ----------------------------------------- | | `enabled` | boolean | `false` | Enable/disable background updates | | `checkInterval` | number | `86400000` | Check interval in milliseconds (24 hours) | | `updateTypes` | BackgroundUpdateType[] | `['both']` | Types of updates to check for | | `autoInstall` | boolean | `false` | Auto-install updates (live updates only) | | `respectBatteryOptimization` | boolean | `true` | Respect system battery optimization | | `allowMeteredConnection` | boolean | `false` | Allow updates on metered connections | | `minimumBatteryLevel` | number | `20` | Minimum battery level (%) | | `requireWifi` | boolean | `false` | Require WiFi connection | | `maxRetries` | number | `3` | Maximum retry attempts | | `retryDelay` | number | `5000` | Retry delay in milliseconds | ### NotificationPreferences | Option | Type | Default | Description | | ------------------ | ------- | ------------------------------ | -------------------------------- | | `title` | string | `'App Update Available'` | Notification title | | `description` | string | `'A new version is available'` | Notification description | | `soundEnabled` | boolean | `true` | Enable notification sound | | `vibrationEnabled` | boolean | `true` | Enable notification vibration | | `showActions` | boolean | `true` | Show notification action buttons | | `priority` | string | `'default'` | Notification priority | | `actionLabels` | object | See defaults | Custom action button labels | ## Troubleshooting ### iOS Issues - Ensure background app refresh is enabled in device settings - Check that the app has notification permissions - Verify BGTaskScheduler identifiers in Info.plist ### Android Issues - Check that the app is not in battery optimization whitelist - Ensure notification permissions are granted - Verify WorkManager dependencies are included ### Common Issues - Background tasks may be limited by the OS - Notifications may not work without proper permissions - Battery optimization can prevent background execution ## Example Implementation ```typescript class BackgroundUpdateManager { private isInitialized = false; async initialize() { if (this.isInitialized) return; // Request notification permissions first const granted = await NativeUpdate.requestNotificationPermissions(); if (!granted) { console.warn('Notification permissions not granted'); return; } // Configure background updates await NativeUpdate.configure({ backgroundUpdate: { enabled: true, checkInterval: 24 * 60 * 60 * 1000, // 24 hours updateTypes: [BackgroundUpdateType.BOTH], autoInstall: false, respectBatteryOptimization: true, notificationPreferences: { title: 'MyApp Update', description: 'New features are available', showActions: true, actionLabels: { updateNow: 'Install Now', updateLater: 'Later', dismiss: 'Skip', }, }, }, }); // Set up event listeners NativeUpdate.addListener( 'backgroundUpdateNotification', (event) => { this.handleNotificationAction(event.action); } ); this.isInitialized = true; } private handleNotificationAction(action: string) { switch (action) { case 'update_now': this.performUpdate(); break; case 'update_later': this.scheduleReminder(); break; case 'dismiss': this.dismissUpdate(); break; } } private async performUpdate() { // Implement your update logic here console.log('Performing update...'); } private scheduleReminder() { // Schedule a reminder for later console.log('Scheduling reminder...'); } private dismissUpdate() { // Handle dismissal console.log('Update dismissed'); } } // Usage const updateManager = new BackgroundUpdateManager(); await updateManager.initialize(); ``` This comprehensive background update feature provides a robust solution for keeping your app updated automatically while providing excellent user experience through native notifications and proper system integration.