native-update 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CapacitorNativeUpdate.podspec +18 -0
- package/LICENSE +21 -0
- package/Readme.md +451 -0
- package/android/build.gradle +92 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +8 -0
- package/android/gradle.properties +17 -0
- package/android/proguard-rules.pro +29 -0
- package/android/settings.gradle +2 -0
- package/android/src/main/AndroidManifest.xml +34 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/AppReviewPlugin.kt +153 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/AppUpdatePlugin.kt +275 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundNotificationManager.kt +390 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdateManager.kt +46 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdatePlugin.kt +333 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundUpdateWorker.kt +251 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/CapacitorNativeUpdatePlugin.kt +265 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/LiveUpdatePlugin.kt +526 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/NotificationActionReceiver.kt +99 -0
- package/android/src/main/java/com/aoneahsan/nativeupdate/SecurityManager.kt +249 -0
- package/dist/esm/__tests__/bundle-manager.test.d.ts +1 -0
- package/dist/esm/__tests__/bundle-manager.test.js +123 -0
- package/dist/esm/__tests__/bundle-manager.test.js.map +1 -0
- package/dist/esm/__tests__/config.test.d.ts +1 -0
- package/dist/esm/__tests__/config.test.js +69 -0
- package/dist/esm/__tests__/config.test.js.map +1 -0
- package/dist/esm/__tests__/integration.test.d.ts +1 -0
- package/dist/esm/__tests__/integration.test.js +78 -0
- package/dist/esm/__tests__/integration.test.js.map +1 -0
- package/dist/esm/__tests__/security.test.d.ts +1 -0
- package/dist/esm/__tests__/security.test.js +54 -0
- package/dist/esm/__tests__/security.test.js.map +1 -0
- package/dist/esm/__tests__/version-manager.test.d.ts +1 -0
- package/dist/esm/__tests__/version-manager.test.js +45 -0
- package/dist/esm/__tests__/version-manager.test.js.map +1 -0
- package/dist/esm/app-review/app-review-manager.d.ts +24 -0
- package/dist/esm/app-review/app-review-manager.js +195 -0
- package/dist/esm/app-review/app-review-manager.js.map +1 -0
- package/dist/esm/app-review/index.d.ts +5 -0
- package/dist/esm/app-review/index.js +6 -0
- package/dist/esm/app-review/index.js.map +1 -0
- package/dist/esm/app-review/platform-review-handler.d.ts +20 -0
- package/dist/esm/app-review/platform-review-handler.js +138 -0
- package/dist/esm/app-review/platform-review-handler.js.map +1 -0
- package/dist/esm/app-review/review-conditions-checker.d.ts +22 -0
- package/dist/esm/app-review/review-conditions-checker.js +155 -0
- package/dist/esm/app-review/review-conditions-checker.js.map +1 -0
- package/dist/esm/app-review/review-rate-limiter.d.ts +23 -0
- package/dist/esm/app-review/review-rate-limiter.js +164 -0
- package/dist/esm/app-review/review-rate-limiter.js.map +1 -0
- package/dist/esm/app-review/types.d.ts +41 -0
- package/dist/esm/app-review/types.js +2 -0
- package/dist/esm/app-review/types.js.map +1 -0
- package/dist/esm/app-update/app-update-checker.d.ts +13 -0
- package/dist/esm/app-update/app-update-checker.js +104 -0
- package/dist/esm/app-update/app-update-checker.js.map +1 -0
- package/dist/esm/app-update/app-update-installer.d.ts +19 -0
- package/dist/esm/app-update/app-update-installer.js +123 -0
- package/dist/esm/app-update/app-update-installer.js.map +1 -0
- package/dist/esm/app-update/app-update-manager.d.ts +28 -0
- package/dist/esm/app-update/app-update-manager.js +199 -0
- package/dist/esm/app-update/app-update-manager.js.map +1 -0
- package/dist/esm/app-update/app-update-notifier.d.ts +14 -0
- package/dist/esm/app-update/app-update-notifier.js +100 -0
- package/dist/esm/app-update/app-update-notifier.js.map +1 -0
- package/dist/esm/app-update/index.d.ts +6 -0
- package/dist/esm/app-update/index.js +7 -0
- package/dist/esm/app-update/index.js.map +1 -0
- package/dist/esm/app-update/platform-app-update.d.ts +19 -0
- package/dist/esm/app-update/platform-app-update.js +129 -0
- package/dist/esm/app-update/platform-app-update.js.map +1 -0
- package/dist/esm/app-update/types.d.ts +58 -0
- package/dist/esm/app-update/types.js +12 -0
- package/dist/esm/app-update/types.js.map +1 -0
- package/dist/esm/background-update/background-scheduler.d.ts +17 -0
- package/dist/esm/background-update/background-scheduler.js +195 -0
- package/dist/esm/background-update/background-scheduler.js.map +1 -0
- package/dist/esm/background-update/index.d.ts +3 -0
- package/dist/esm/background-update/index.js +3 -0
- package/dist/esm/background-update/index.js.map +1 -0
- package/dist/esm/background-update/notification-manager.d.ts +29 -0
- package/dist/esm/background-update/notification-manager.js +89 -0
- package/dist/esm/background-update/notification-manager.js.map +1 -0
- package/dist/esm/core/analytics.d.ts +70 -0
- package/dist/esm/core/analytics.js +137 -0
- package/dist/esm/core/analytics.js.map +1 -0
- package/dist/esm/core/cache-manager.d.ts +72 -0
- package/dist/esm/core/cache-manager.js +275 -0
- package/dist/esm/core/cache-manager.js.map +1 -0
- package/dist/esm/core/config.d.ts +48 -0
- package/dist/esm/core/config.js +83 -0
- package/dist/esm/core/config.js.map +1 -0
- package/dist/esm/core/errors.d.ts +51 -0
- package/dist/esm/core/errors.js +80 -0
- package/dist/esm/core/errors.js.map +1 -0
- package/dist/esm/core/logger.d.ts +21 -0
- package/dist/esm/core/logger.js +109 -0
- package/dist/esm/core/logger.js.map +1 -0
- package/dist/esm/core/performance.d.ts +53 -0
- package/dist/esm/core/performance.js +140 -0
- package/dist/esm/core/performance.js.map +1 -0
- package/dist/esm/core/plugin-manager.d.ts +66 -0
- package/dist/esm/core/plugin-manager.js +148 -0
- package/dist/esm/core/plugin-manager.js.map +1 -0
- package/dist/esm/core/security.d.ts +93 -0
- package/dist/esm/core/security.js +315 -0
- package/dist/esm/core/security.js.map +1 -0
- package/dist/esm/definitions.d.ts +639 -0
- package/dist/esm/definitions.js +103 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +12 -0
- package/dist/esm/index.js +16 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/live-update/bundle-manager.d.ts +94 -0
- package/dist/esm/live-update/bundle-manager.js +310 -0
- package/dist/esm/live-update/bundle-manager.js.map +1 -0
- package/dist/esm/live-update/certificate-pinning.d.ts +38 -0
- package/dist/esm/live-update/certificate-pinning.js +78 -0
- package/dist/esm/live-update/certificate-pinning.js.map +1 -0
- package/dist/esm/live-update/download-manager.d.ts +67 -0
- package/dist/esm/live-update/download-manager.js +319 -0
- package/dist/esm/live-update/download-manager.js.map +1 -0
- package/dist/esm/live-update/update-manager.d.ts +52 -0
- package/dist/esm/live-update/update-manager.js +294 -0
- package/dist/esm/live-update/update-manager.js.map +1 -0
- package/dist/esm/live-update/version-manager.d.ts +84 -0
- package/dist/esm/live-update/version-manager.js +335 -0
- package/dist/esm/live-update/version-manager.js.map +1 -0
- package/dist/esm/plugin.d.ts +6 -0
- package/dist/esm/plugin.js +283 -0
- package/dist/esm/plugin.js.map +1 -0
- package/dist/esm/security/crypto.d.ts +25 -0
- package/dist/esm/security/crypto.js +70 -0
- package/dist/esm/security/crypto.js.map +1 -0
- package/dist/esm/security/validator.d.ts +60 -0
- package/dist/esm/security/validator.js +143 -0
- package/dist/esm/security/validator.js.map +1 -0
- package/dist/esm/web.d.ts +74 -0
- package/dist/esm/web.js +595 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +2 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.esm.js +2 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/plugin.js +3 -0
- package/dist/plugin.js.map +1 -0
- package/docs/APP_REVIEW_GUIDE.md +768 -0
- package/docs/BUNDLE_SIGNING.md +264 -0
- package/docs/LIVE_UPDATES_GUIDE.md +650 -0
- package/docs/MIGRATION.md +192 -0
- package/docs/NATIVE_UPDATES_GUIDE.md +694 -0
- package/docs/QUICK_START.md +606 -0
- package/docs/README.md +111 -0
- package/docs/REMAINING_FEATURES.md +139 -0
- package/docs/api/app-review-api.md +259 -0
- package/docs/api/app-update-api.md +238 -0
- package/docs/api/events-api.md +451 -0
- package/docs/api/live-update-api.md +265 -0
- package/docs/background-updates.md +392 -0
- package/docs/examples/advanced-scenarios.md +410 -0
- package/docs/examples/basic-usage.md +185 -0
- package/docs/features/app-reviews.md +975 -0
- package/docs/features/app-updates.md +785 -0
- package/docs/features/live-updates.md +633 -0
- package/docs/getting-started/configuration.md +468 -0
- package/docs/getting-started/installation.md +209 -0
- package/docs/getting-started/quick-start.md +379 -0
- package/docs/guides/deployment-guide.md +333 -0
- package/docs/guides/migration-from-codepush.md +142 -0
- package/docs/guides/security-best-practices.md +1057 -0
- package/docs/guides/testing-guide.md +373 -0
- package/docs/production-readiness.md +478 -0
- package/docs/security/certificate-pinning.md +122 -0
- package/docs/server-requirements.md +147 -0
- package/ios/Plugin/AppReview/AppReviewPlugin.swift +158 -0
- package/ios/Plugin/AppUpdate/AppUpdatePlugin.swift +234 -0
- package/ios/Plugin/BackgroundUpdate/BackgroundNotificationManager.swift +329 -0
- package/ios/Plugin/BackgroundUpdate/BackgroundUpdatePlugin.swift +396 -0
- package/ios/Plugin/CapacitorNativeUpdatePlugin.m +45 -0
- package/ios/Plugin/CapacitorNativeUpdatePlugin.swift +190 -0
- package/ios/Plugin/Info.plist +43 -0
- package/ios/Plugin/LiveUpdate/LiveUpdatePlugin.swift +689 -0
- package/ios/Plugin/LiveUpdate/WebViewConfiguration.swift +45 -0
- package/ios/Plugin/Security/SecurityManager.swift +289 -0
- package/package.json +90 -0
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
# Advanced Scenarios
|
|
2
|
+
|
|
3
|
+
This guide covers complex use cases and advanced patterns for the Capacitor Native Update plugin.
|
|
4
|
+
|
|
5
|
+
## Delta Updates
|
|
6
|
+
|
|
7
|
+
Minimize download sizes by only downloading changed files:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { CapacitorNativeUpdate } from 'capacitor-native-update';
|
|
11
|
+
|
|
12
|
+
async function checkForDeltaUpdate() {
|
|
13
|
+
const currentManifest = await CapacitorNativeUpdate.getCurrentManifest();
|
|
14
|
+
|
|
15
|
+
const result = await CapacitorNativeUpdate.checkForUpdate({
|
|
16
|
+
updateUrl: 'https://your-update-server.com/api/check',
|
|
17
|
+
currentVersion: currentManifest.version,
|
|
18
|
+
currentChecksum: currentManifest.checksum,
|
|
19
|
+
supportsDelta: true
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (result.updateAvailable && result.deltaAvailable) {
|
|
23
|
+
console.log(`Delta update available: ${result.deltaSize} bytes`);
|
|
24
|
+
await downloadDeltaUpdate(result.deltaUrl);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function downloadDeltaUpdate(deltaUrl: string) {
|
|
29
|
+
const download = await CapacitorNativeUpdate.downloadUpdate({
|
|
30
|
+
url: deltaUrl,
|
|
31
|
+
isDelta: true
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Apply delta patch
|
|
35
|
+
await CapacitorNativeUpdate.applyDelta({
|
|
36
|
+
bundleId: download.bundleId,
|
|
37
|
+
baseVersion: getCurrentVersion()
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Update Channels
|
|
43
|
+
|
|
44
|
+
Manage different release tracks:
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
// Configure update channels
|
|
48
|
+
enum UpdateChannel {
|
|
49
|
+
PRODUCTION = 'production',
|
|
50
|
+
BETA = 'beta',
|
|
51
|
+
DEVELOPMENT = 'development'
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function setupUpdateChannel(channel: UpdateChannel) {
|
|
55
|
+
await CapacitorNativeUpdate.configure({
|
|
56
|
+
updateChannel: channel,
|
|
57
|
+
updateUrl: `https://updates.example.com/api/${channel}/check`
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Switch channels based on user preference
|
|
62
|
+
async function switchToBetaChannel() {
|
|
63
|
+
await setupUpdateChannel(UpdateChannel.BETA);
|
|
64
|
+
|
|
65
|
+
// Check for updates in the new channel
|
|
66
|
+
const result = await CapacitorNativeUpdate.checkForUpdate({
|
|
67
|
+
currentVersion: await getCurrentVersion()
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (result.updateAvailable) {
|
|
71
|
+
console.log(`Beta update ${result.version} available`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Staged Rollouts
|
|
77
|
+
|
|
78
|
+
Implement gradual update deployment:
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
async function checkStagedUpdate() {
|
|
82
|
+
const deviceId = await getDeviceId();
|
|
83
|
+
const rolloutPercentage = hashDeviceId(deviceId) % 100;
|
|
84
|
+
|
|
85
|
+
const result = await CapacitorNativeUpdate.checkForUpdate({
|
|
86
|
+
updateUrl: 'https://your-update-server.com/api/check',
|
|
87
|
+
currentVersion: '1.0.0',
|
|
88
|
+
metadata: {
|
|
89
|
+
deviceId,
|
|
90
|
+
rolloutGroup: rolloutPercentage
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (result.updateAvailable && result.rolloutPercentage >= rolloutPercentage) {
|
|
95
|
+
// Device is eligible for update
|
|
96
|
+
await downloadAndInstall(result);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Background Updates
|
|
102
|
+
|
|
103
|
+
Download updates in the background without interrupting users:
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
async function setupBackgroundUpdates() {
|
|
107
|
+
// Configure background update behavior
|
|
108
|
+
await CapacitorNativeUpdate.configure({
|
|
109
|
+
backgroundUpdateMode: 'wifi-only',
|
|
110
|
+
autoInstallMode: 'on-restart'
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Schedule background update checks
|
|
114
|
+
await CapacitorNativeUpdate.scheduleBackgroundCheck({
|
|
115
|
+
interval: 14400000, // 4 hours
|
|
116
|
+
requiresWifi: true,
|
|
117
|
+
requiresCharging: false
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Handle background update events
|
|
122
|
+
CapacitorNativeUpdate.addListener('backgroundUpdateReady', (event) => {
|
|
123
|
+
// Notify user that update is ready
|
|
124
|
+
showUpdateNotification({
|
|
125
|
+
version: event.version,
|
|
126
|
+
releaseNotes: event.releaseNotes
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Rollback Strategies
|
|
132
|
+
|
|
133
|
+
Implement automatic rollback on update failures:
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
async function safeUpdate() {
|
|
137
|
+
// Save current version info before update
|
|
138
|
+
const backup = await CapacitorNativeUpdate.createBackup();
|
|
139
|
+
|
|
140
|
+
try {
|
|
141
|
+
// Attempt update
|
|
142
|
+
await CapacitorNativeUpdate.installUpdate({
|
|
143
|
+
bundleId: 'new-update-id',
|
|
144
|
+
validateAfterInstall: true
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// Verify update success
|
|
148
|
+
const health = await performHealthCheck();
|
|
149
|
+
if (!health.passed) {
|
|
150
|
+
throw new Error('Health check failed');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Confirm successful update
|
|
154
|
+
await CapacitorNativeUpdate.confirmUpdate();
|
|
155
|
+
} catch (error) {
|
|
156
|
+
console.error('Update failed, rolling back:', error);
|
|
157
|
+
|
|
158
|
+
// Automatic rollback
|
|
159
|
+
await CapacitorNativeUpdate.rollback({
|
|
160
|
+
backupId: backup.id
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// Report failure to analytics
|
|
164
|
+
reportUpdateFailure(error);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async function performHealthCheck(): Promise<{ passed: boolean }> {
|
|
169
|
+
// Custom health check logic
|
|
170
|
+
try {
|
|
171
|
+
// Test critical functionality
|
|
172
|
+
await testApiConnection();
|
|
173
|
+
await testDatabaseAccess();
|
|
174
|
+
await testUIComponents();
|
|
175
|
+
|
|
176
|
+
return { passed: true };
|
|
177
|
+
} catch {
|
|
178
|
+
return { passed: false };
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Multi-Bundle Management
|
|
184
|
+
|
|
185
|
+
Handle multiple update bundles for A/B testing:
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
interface ABTestConfig {
|
|
189
|
+
testId: string;
|
|
190
|
+
variants: {
|
|
191
|
+
control: string;
|
|
192
|
+
treatment: string;
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async function setupABTest(config: ABTestConfig) {
|
|
197
|
+
const variant = await determineVariant(config.testId);
|
|
198
|
+
|
|
199
|
+
// Download appropriate bundle
|
|
200
|
+
const bundleUrl = variant === 'treatment'
|
|
201
|
+
? config.variants.treatment
|
|
202
|
+
: config.variants.control;
|
|
203
|
+
|
|
204
|
+
const download = await CapacitorNativeUpdate.downloadUpdate({
|
|
205
|
+
url: bundleUrl,
|
|
206
|
+
metadata: {
|
|
207
|
+
testId: config.testId,
|
|
208
|
+
variant
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// Install with test metadata
|
|
213
|
+
await CapacitorNativeUpdate.installUpdate({
|
|
214
|
+
bundleId: download.bundleId,
|
|
215
|
+
preserveData: true
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Custom Update UI
|
|
221
|
+
|
|
222
|
+
Create sophisticated update experiences:
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
class UpdateManager {
|
|
226
|
+
private updateState: UpdateState = { status: 'idle' };
|
|
227
|
+
|
|
228
|
+
async checkAndPromptUpdate() {
|
|
229
|
+
// Check for update
|
|
230
|
+
const result = await CapacitorNativeUpdate.checkForUpdate({
|
|
231
|
+
updateUrl: 'https://your-update-server.com/api/check',
|
|
232
|
+
currentVersion: await this.getCurrentVersion()
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
if (!result.updateAvailable) return;
|
|
236
|
+
|
|
237
|
+
// Show custom update dialog
|
|
238
|
+
const userChoice = await this.showUpdateDialog({
|
|
239
|
+
version: result.version,
|
|
240
|
+
releaseNotes: result.releaseNotes,
|
|
241
|
+
size: result.size,
|
|
242
|
+
criticalUpdate: result.priority === 'critical'
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
if (userChoice === 'update') {
|
|
246
|
+
await this.performUpdate(result);
|
|
247
|
+
} else if (userChoice === 'remind') {
|
|
248
|
+
await this.scheduleReminder();
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
private async performUpdate(updateInfo: UpdateInfo) {
|
|
253
|
+
this.updateState = { status: 'downloading', progress: 0 };
|
|
254
|
+
|
|
255
|
+
// Download with progress tracking
|
|
256
|
+
const downloadListener = CapacitorNativeUpdate.addListener(
|
|
257
|
+
'downloadProgress',
|
|
258
|
+
(progress) => {
|
|
259
|
+
this.updateState = {
|
|
260
|
+
status: 'downloading',
|
|
261
|
+
progress: progress.percent
|
|
262
|
+
};
|
|
263
|
+
this.updateUI();
|
|
264
|
+
}
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
try {
|
|
268
|
+
const download = await CapacitorNativeUpdate.downloadUpdate({
|
|
269
|
+
url: updateInfo.downloadUrl
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
this.updateState = { status: 'installing' };
|
|
273
|
+
this.updateUI();
|
|
274
|
+
|
|
275
|
+
await CapacitorNativeUpdate.installUpdate({
|
|
276
|
+
bundleId: download.bundleId
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
this.updateState = { status: 'ready' };
|
|
280
|
+
await this.promptRestart();
|
|
281
|
+
} finally {
|
|
282
|
+
downloadListener.remove();
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Security-Enhanced Updates
|
|
289
|
+
|
|
290
|
+
Implement advanced security measures:
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
async function secureUpdateCheck() {
|
|
294
|
+
// Generate request signature
|
|
295
|
+
const timestamp = Date.now();
|
|
296
|
+
const nonce = generateNonce();
|
|
297
|
+
const signature = await signRequest({
|
|
298
|
+
timestamp,
|
|
299
|
+
nonce,
|
|
300
|
+
version: getCurrentVersion()
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
const result = await CapacitorNativeUpdate.checkForUpdate({
|
|
304
|
+
updateUrl: 'https://your-update-server.com/api/check',
|
|
305
|
+
currentVersion: getCurrentVersion(),
|
|
306
|
+
headers: {
|
|
307
|
+
'X-Timestamp': timestamp.toString(),
|
|
308
|
+
'X-Nonce': nonce,
|
|
309
|
+
'X-Signature': signature
|
|
310
|
+
},
|
|
311
|
+
certificatePins: [
|
|
312
|
+
'sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='
|
|
313
|
+
]
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
// Verify response signature
|
|
317
|
+
if (!await verifyUpdateSignature(result)) {
|
|
318
|
+
throw new Error('Invalid update signature');
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return result;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
async function downloadWithIntegrityCheck(url: string, expectedHash: string) {
|
|
325
|
+
const download = await CapacitorNativeUpdate.downloadUpdate({
|
|
326
|
+
url,
|
|
327
|
+
validateChecksum: true,
|
|
328
|
+
expectedChecksum: expectedHash,
|
|
329
|
+
algorithm: 'sha256'
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
// Additional verification
|
|
333
|
+
const verified = await CapacitorNativeUpdate.verifyBundle({
|
|
334
|
+
bundleId: download.bundleId,
|
|
335
|
+
publicKey: await getPublicKey()
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
if (!verified.valid) {
|
|
339
|
+
throw new Error('Bundle verification failed');
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
return download;
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## Performance Monitoring
|
|
347
|
+
|
|
348
|
+
Track update performance and success rates:
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
class UpdateMetrics {
|
|
352
|
+
async trackUpdateCycle() {
|
|
353
|
+
const startTime = Date.now();
|
|
354
|
+
const metrics: UpdateMetrics = {
|
|
355
|
+
checkStarted: startTime,
|
|
356
|
+
downloadStarted: 0,
|
|
357
|
+
downloadCompleted: 0,
|
|
358
|
+
installStarted: 0,
|
|
359
|
+
installCompleted: 0,
|
|
360
|
+
errors: []
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
try {
|
|
364
|
+
// Check phase
|
|
365
|
+
const result = await CapacitorNativeUpdate.checkForUpdate({
|
|
366
|
+
updateUrl: 'https://your-update-server.com/api/check',
|
|
367
|
+
currentVersion: getCurrentVersion()
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
if (!result.updateAvailable) {
|
|
371
|
+
metrics.checkCompleted = Date.now();
|
|
372
|
+
await this.reportMetrics(metrics);
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Download phase
|
|
377
|
+
metrics.downloadStarted = Date.now();
|
|
378
|
+
const download = await CapacitorNativeUpdate.downloadUpdate({
|
|
379
|
+
url: result.downloadUrl
|
|
380
|
+
});
|
|
381
|
+
metrics.downloadCompleted = Date.now();
|
|
382
|
+
metrics.downloadSize = download.size;
|
|
383
|
+
|
|
384
|
+
// Install phase
|
|
385
|
+
metrics.installStarted = Date.now();
|
|
386
|
+
await CapacitorNativeUpdate.installUpdate({
|
|
387
|
+
bundleId: download.bundleId
|
|
388
|
+
});
|
|
389
|
+
metrics.installCompleted = Date.now();
|
|
390
|
+
|
|
391
|
+
metrics.success = true;
|
|
392
|
+
} catch (error) {
|
|
393
|
+
metrics.errors.push({
|
|
394
|
+
phase: this.getCurrentPhase(metrics),
|
|
395
|
+
error: error.message,
|
|
396
|
+
timestamp: Date.now()
|
|
397
|
+
});
|
|
398
|
+
metrics.success = false;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
await this.reportMetrics(metrics);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
## Next Steps
|
|
407
|
+
|
|
408
|
+
- Review [Integration Examples](./integration-examples.md) for framework-specific implementations
|
|
409
|
+
- See the [API Reference](../api/README.md) for detailed method documentation
|
|
410
|
+
- Check [Basic Usage](./basic-usage.md) for simpler examples
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# Basic Usage Examples
|
|
2
|
+
|
|
3
|
+
This guide demonstrates basic usage patterns for the Capacitor Native Update plugin.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
yarn add capacitor-native-update
|
|
9
|
+
npx cap sync
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Simple Live Update Check
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
import { CapacitorNativeUpdate } from 'capacitor-native-update';
|
|
16
|
+
|
|
17
|
+
// Check for updates on app startup
|
|
18
|
+
async function checkForUpdates() {
|
|
19
|
+
try {
|
|
20
|
+
const result = await CapacitorNativeUpdate.checkForUpdate({
|
|
21
|
+
updateUrl: 'https://your-update-server.com/api/check',
|
|
22
|
+
currentVersion: '1.0.0'
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
if (result.updateAvailable) {
|
|
26
|
+
console.log(`Update available: ${result.version}`);
|
|
27
|
+
// Download and install the update
|
|
28
|
+
await downloadAndInstall(result.downloadUrl);
|
|
29
|
+
}
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.error('Update check failed:', error);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function downloadAndInstall(downloadUrl: string) {
|
|
36
|
+
// Download the update
|
|
37
|
+
const download = await CapacitorNativeUpdate.downloadUpdate({
|
|
38
|
+
url: downloadUrl
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Monitor download progress
|
|
42
|
+
CapacitorNativeUpdate.addListener('downloadProgress', (progress) => {
|
|
43
|
+
console.log(`Download progress: ${progress.percent}%`);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Install the update
|
|
47
|
+
await CapacitorNativeUpdate.installUpdate({
|
|
48
|
+
bundleId: download.bundleId
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// Reload the app with new bundle
|
|
52
|
+
await CapacitorNativeUpdate.reloadApp();
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Basic App Store Update Check
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// Check if a native app update is available
|
|
60
|
+
async function checkAppStoreUpdate() {
|
|
61
|
+
const result = await CapacitorNativeUpdate.checkAppUpdate();
|
|
62
|
+
|
|
63
|
+
if (result.updateAvailable) {
|
|
64
|
+
// Show update prompt to user
|
|
65
|
+
const shouldUpdate = confirm(
|
|
66
|
+
`Version ${result.availableVersion} is available. Update now?`
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
if (shouldUpdate) {
|
|
70
|
+
// Open app store for update
|
|
71
|
+
await CapacitorNativeUpdate.openAppStore();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Simple App Review Request
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
// Request app review after positive user action
|
|
81
|
+
async function requestReview() {
|
|
82
|
+
try {
|
|
83
|
+
const result = await CapacitorNativeUpdate.requestReview();
|
|
84
|
+
|
|
85
|
+
if (result.displayed) {
|
|
86
|
+
console.log('Review dialog was shown');
|
|
87
|
+
// Track that review was requested
|
|
88
|
+
}
|
|
89
|
+
} catch (error) {
|
|
90
|
+
console.error('Could not request review:', error);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Example: Request review after successful task completion
|
|
95
|
+
async function onTaskCompleted() {
|
|
96
|
+
// Your task logic here
|
|
97
|
+
|
|
98
|
+
// Check if it's a good time to ask for review
|
|
99
|
+
const completedTasks = getCompletedTaskCount();
|
|
100
|
+
if (completedTasks === 5) {
|
|
101
|
+
await requestReview();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Configuration Options
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
// Initialize with custom configuration
|
|
110
|
+
CapacitorNativeUpdate.configure({
|
|
111
|
+
// Live update settings
|
|
112
|
+
autoCheckOnStart: true,
|
|
113
|
+
updateCheckInterval: 3600000, // 1 hour
|
|
114
|
+
updateChannel: 'production',
|
|
115
|
+
|
|
116
|
+
// Security settings
|
|
117
|
+
enableSignatureVerification: true,
|
|
118
|
+
publicKey: 'your-public-key',
|
|
119
|
+
|
|
120
|
+
// App review settings
|
|
121
|
+
minimumDaysSinceInstall: 3,
|
|
122
|
+
minimumDaysSinceLastPrompt: 30
|
|
123
|
+
});
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Error Handling
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// Comprehensive error handling
|
|
130
|
+
async function safeUpdateCheck() {
|
|
131
|
+
try {
|
|
132
|
+
const result = await CapacitorNativeUpdate.checkForUpdate({
|
|
133
|
+
updateUrl: 'https://your-update-server.com/api/check',
|
|
134
|
+
currentVersion: '1.0.0'
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
if (result.updateAvailable) {
|
|
138
|
+
await handleUpdate(result);
|
|
139
|
+
}
|
|
140
|
+
} catch (error) {
|
|
141
|
+
if (error.code === 'NETWORK_ERROR') {
|
|
142
|
+
console.log('No internet connection');
|
|
143
|
+
} else if (error.code === 'INVALID_RESPONSE') {
|
|
144
|
+
console.error('Invalid server response');
|
|
145
|
+
} else {
|
|
146
|
+
console.error('Unexpected error:', error);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Event Listeners
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
// Set up event listeners
|
|
156
|
+
function setupUpdateListeners() {
|
|
157
|
+
// Download progress
|
|
158
|
+
CapacitorNativeUpdate.addListener('downloadProgress', (event) => {
|
|
159
|
+
updateProgressBar(event.percent);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Update installed
|
|
163
|
+
CapacitorNativeUpdate.addListener('updateInstalled', (event) => {
|
|
164
|
+
console.log(`Update ${event.version} installed successfully`);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// Update failed
|
|
168
|
+
CapacitorNativeUpdate.addListener('updateFailed', (event) => {
|
|
169
|
+
console.error(`Update failed: ${event.error}`);
|
|
170
|
+
// Optionally rollback
|
|
171
|
+
CapacitorNativeUpdate.rollback();
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Clean up listeners when done
|
|
176
|
+
function cleanup() {
|
|
177
|
+
CapacitorNativeUpdate.removeAllListeners();
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Next Steps
|
|
182
|
+
|
|
183
|
+
- See [Advanced Scenarios](./advanced-scenarios.md) for more complex use cases
|
|
184
|
+
- Check [Integration Examples](./integration-examples.md) for framework-specific implementations
|
|
185
|
+
- Read the [API Reference](../api/README.md) for complete method documentation
|