native-update 1.0.3 → 1.0.5
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/docs/APP_REVIEW_GUIDE.md +2 -2
- package/docs/BUNDLE_SIGNING.md +10 -4
- package/docs/LIVE_UPDATES_GUIDE.md +152 -127
- package/docs/MIGRATION.md +2 -2
- package/docs/NATIVE_UPDATES_GUIDE.md +17 -16
- package/docs/QUICK_START.md +64 -75
- package/docs/README.md +4 -5
- package/docs/api/app-review-api.md +1 -21
- package/docs/api/app-update-api.md +18 -110
- package/docs/api/events-api.md +83 -334
- package/docs/api/live-update-api.md +63 -86
- package/docs/examples/advanced-scenarios.md +72 -88
- package/docs/examples/basic-usage.md +41 -38
- package/docs/features/app-reviews.md +1 -1
- package/docs/features/app-updates.md +1 -1
- package/docs/features/live-updates.md +23 -14
- package/docs/getting-started/configuration.md +1 -1
- package/docs/getting-started/installation.md +2 -2
- package/docs/getting-started/quick-start.md +3 -3
- package/docs/guides/migration-from-codepush.md +10 -11
- package/docs/guides/security-best-practices.md +3 -3
- package/docs/guides/testing-guide.md +27 -28
- package/package.json +1 -1
package/docs/QUICK_START.md
CHANGED
|
@@ -70,26 +70,19 @@ import { NativeUpdate } from 'native-update';
|
|
|
70
70
|
export class LiveUpdateService {
|
|
71
71
|
async checkAndApplyUpdates() {
|
|
72
72
|
try {
|
|
73
|
-
// 1.
|
|
74
|
-
const
|
|
75
|
-
await NativeUpdate.checkForUpdate();
|
|
73
|
+
// 1. Sync with the update server
|
|
74
|
+
const result = await NativeUpdate.sync();
|
|
76
75
|
|
|
77
|
-
if (
|
|
76
|
+
if (result.status === 'UP_TO_DATE') {
|
|
78
77
|
console.log('No updates available');
|
|
79
78
|
return;
|
|
80
79
|
}
|
|
81
80
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
console.log(`Download: ${progress.percent}%`);
|
|
88
|
-
},
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
// 3. Apply the update (app will restart)
|
|
92
|
-
await NativeUpdate.applyUpdate();
|
|
81
|
+
if (result.status === 'UPDATE_INSTALLED') {
|
|
82
|
+
console.log(`Update ${result.bundle?.version} installed!`);
|
|
83
|
+
// Reload to apply the update
|
|
84
|
+
await NativeUpdate.reload();
|
|
85
|
+
}
|
|
93
86
|
} catch (error) {
|
|
94
87
|
console.error('Update failed:', error);
|
|
95
88
|
}
|
|
@@ -107,42 +100,41 @@ export class UpdateUIService {
|
|
|
107
100
|
) {}
|
|
108
101
|
|
|
109
102
|
async checkForUpdatesWithUI() {
|
|
110
|
-
const
|
|
111
|
-
await NativeUpdate.checkForUpdate();
|
|
103
|
+
const result = await NativeUpdate.sync();
|
|
112
104
|
|
|
113
|
-
if (
|
|
105
|
+
if (result.status === 'UP_TO_DATE') return;
|
|
114
106
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
107
|
+
if (result.status === 'UPDATE_AVAILABLE') {
|
|
108
|
+
// Show update dialog
|
|
109
|
+
const alert = await this.alertController.create({
|
|
110
|
+
header: 'Update Available',
|
|
111
|
+
message: `Version ${result.bundle?.version} is ready!\n\nBug fixes and improvements`,
|
|
112
|
+
buttons: [
|
|
113
|
+
{ text: 'Later', role: 'cancel' },
|
|
114
|
+
{
|
|
115
|
+
text: 'Update Now',
|
|
116
|
+
handler: () => this.applyUpdate(),
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
});
|
|
127
120
|
|
|
128
|
-
|
|
121
|
+
await alert.present();
|
|
122
|
+
} else if (result.status === 'UPDATE_INSTALLED') {
|
|
123
|
+
// Update already installed, just need to reload
|
|
124
|
+
await NativeUpdate.reload();
|
|
125
|
+
}
|
|
129
126
|
}
|
|
130
127
|
|
|
131
|
-
private async
|
|
128
|
+
private async applyUpdate() {
|
|
132
129
|
const loading = await this.loadingController.create({
|
|
133
|
-
message: '
|
|
130
|
+
message: 'Applying update...',
|
|
134
131
|
});
|
|
135
132
|
await loading.present();
|
|
136
133
|
|
|
137
134
|
try {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
},
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
loading.message = 'Installing...';
|
|
145
|
-
await NativeUpdate.applyUpdate();
|
|
135
|
+
// The sync method already downloaded the update
|
|
136
|
+
// We just need to reload the app
|
|
137
|
+
await NativeUpdate.reload();
|
|
146
138
|
} catch (error) {
|
|
147
139
|
await loading.dismiss();
|
|
148
140
|
// Show error
|
|
@@ -179,7 +171,7 @@ Check for app store updates and install them!
|
|
|
179
171
|
export class NativeUpdateService {
|
|
180
172
|
async checkForAppStoreUpdates() {
|
|
181
173
|
try {
|
|
182
|
-
const result = await NativeUpdate.
|
|
174
|
+
const result = await NativeUpdate.getAppUpdateInfo();
|
|
183
175
|
|
|
184
176
|
if (!result.updateAvailable) {
|
|
185
177
|
console.log('App is up to date');
|
|
@@ -200,7 +192,7 @@ export class NativeUpdateService {
|
|
|
200
192
|
private async handleAndroidUpdate(result: any) {
|
|
201
193
|
if (result.immediateUpdateAllowed) {
|
|
202
194
|
// Critical update - must install
|
|
203
|
-
await NativeUpdate.
|
|
195
|
+
await NativeUpdate.performImmediateUpdate();
|
|
204
196
|
} else {
|
|
205
197
|
// Optional update - download in background
|
|
206
198
|
await NativeUpdate.startFlexibleUpdate();
|
|
@@ -246,19 +238,21 @@ export class AndroidUpdateProgress {
|
|
|
246
238
|
);
|
|
247
239
|
|
|
248
240
|
// Handle completion
|
|
249
|
-
NativeUpdate.addListener('
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
241
|
+
NativeUpdate.addListener('updateStateChanged', async (event) => {
|
|
242
|
+
if (event.status === 'DOWNLOADED') {
|
|
243
|
+
const alert = await this.alertController.create({
|
|
244
|
+
header: 'Update Ready',
|
|
245
|
+
message: 'Update has been downloaded. Install now?',
|
|
246
|
+
buttons: [
|
|
247
|
+
{ text: 'Later' },
|
|
248
|
+
{
|
|
249
|
+
text: 'Install',
|
|
250
|
+
handler: () => NativeUpdate.completeFlexibleUpdate(),
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
});
|
|
254
|
+
await alert.present();
|
|
255
|
+
}
|
|
262
256
|
});
|
|
263
257
|
}
|
|
264
258
|
}
|
|
@@ -422,12 +416,9 @@ export class AppComponent implements OnInit {
|
|
|
422
416
|
// Live Updates
|
|
423
417
|
private async checkLiveUpdates() {
|
|
424
418
|
try {
|
|
425
|
-
const
|
|
426
|
-
|
|
427
|
-
if (available) {
|
|
428
|
-
// Auto-download in background
|
|
429
|
-
await NativeUpdate.downloadUpdate();
|
|
419
|
+
const result = await NativeUpdate.sync();
|
|
430
420
|
|
|
421
|
+
if (result.status === 'UPDATE_INSTALLED') {
|
|
431
422
|
// Notify user
|
|
432
423
|
const toast = await this.toastCtrl.create({
|
|
433
424
|
message: 'Update ready! Restart to apply.',
|
|
@@ -435,7 +426,7 @@ export class AppComponent implements OnInit {
|
|
|
435
426
|
buttons: [
|
|
436
427
|
{
|
|
437
428
|
text: 'Restart',
|
|
438
|
-
handler: () => NativeUpdate.
|
|
429
|
+
handler: () => NativeUpdate.reload(),
|
|
439
430
|
},
|
|
440
431
|
],
|
|
441
432
|
});
|
|
@@ -462,7 +453,7 @@ export class AppComponent implements OnInit {
|
|
|
462
453
|
|
|
463
454
|
private async checkNativeUpdates() {
|
|
464
455
|
try {
|
|
465
|
-
const result = await NativeUpdate.
|
|
456
|
+
const result = await NativeUpdate.getAppUpdateInfo();
|
|
466
457
|
|
|
467
458
|
if (result.updateAvailable && result.flexibleUpdateAllowed) {
|
|
468
459
|
// Start background download for Android
|
|
@@ -544,11 +535,10 @@ curl -X POST http://localhost:3000/api/v1/bundles \
|
|
|
544
535
|
### 3. Test App Reviews
|
|
545
536
|
|
|
546
537
|
```typescript
|
|
547
|
-
//
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
await NativeUpdate.requestReview({ force: true });
|
|
538
|
+
// Test review prompts
|
|
539
|
+
// Note: Reviews may not show in development builds
|
|
540
|
+
// Test with TestFlight (iOS) or Internal Test Track (Android)
|
|
541
|
+
await NativeUpdate.requestReview();
|
|
552
542
|
```
|
|
553
543
|
|
|
554
544
|
## What's Next?
|
|
@@ -569,20 +559,19 @@ Now that you have the basics working:
|
|
|
569
559
|
- [Live Updates Guide](./LIVE_UPDATES_GUIDE.md) - Complete OTA implementation
|
|
570
560
|
- [Native Updates Guide](./NATIVE_UPDATES_GUIDE.md) - Platform-specific details
|
|
571
561
|
- [App Review Guide](./APP_REVIEW_GUIDE.md) - Maximize review rates
|
|
572
|
-
- [Security Guide](./
|
|
573
|
-
- [API Reference](
|
|
562
|
+
- [Security Guide](./guides/security-best-practices.md) - Best practices
|
|
563
|
+
- [API Reference](./api/live-update-api.md) - All methods and options
|
|
574
564
|
|
|
575
565
|
## Troubleshooting
|
|
576
566
|
|
|
577
567
|
### Live Updates Not Working?
|
|
578
568
|
|
|
579
569
|
```typescript
|
|
580
|
-
// Enable debug logging
|
|
581
|
-
|
|
570
|
+
// Enable debug logging in your app
|
|
571
|
+
console.log('Checking update configuration...');
|
|
582
572
|
|
|
583
|
-
//
|
|
584
|
-
|
|
585
|
-
console.log('Update URL:', config.updateUrl);
|
|
573
|
+
// Configuration is set in capacitor.config.json
|
|
574
|
+
// Check your config file for updateUrl and other settings
|
|
586
575
|
```
|
|
587
576
|
|
|
588
577
|
### Native Updates Not Detected?
|
package/docs/README.md
CHANGED
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
> - Bundle storage and CDN
|
|
8
8
|
> - Signing and security services
|
|
9
9
|
>
|
|
10
|
-
> See [ROADMAP.md](../ROADMAP.md) for complete requirements.
|
|
11
10
|
|
|
12
11
|
Welcome to the comprehensive documentation for **Capacitor Native Update**, a foundation plugin that provides architecture for a complete update lifecycle management solution for Capacitor applications.
|
|
13
12
|
|
|
@@ -34,8 +33,9 @@ Created by **Ahsan Mahmood** and open-sourced for the developer community, this
|
|
|
34
33
|
### Guides
|
|
35
34
|
|
|
36
35
|
- [**Security Best Practices**](./guides/security-best-practices.md) - Implement secure updates
|
|
37
|
-
- [**Migration
|
|
38
|
-
- [**
|
|
36
|
+
- [**Migration from CodePush**](./guides/migration-from-codepush.md) - Migrate from CodePush
|
|
37
|
+
- [**Testing Guide**](./guides/testing-guide.md) - Testing your update implementation
|
|
38
|
+
- [**Deployment Guide**](./guides/deployment-guide.md) - Deploy to production
|
|
39
39
|
|
|
40
40
|
### API Reference
|
|
41
41
|
|
|
@@ -47,8 +47,7 @@ Created by **Ahsan Mahmood** and open-sourced for the developer community, this
|
|
|
47
47
|
### Examples
|
|
48
48
|
|
|
49
49
|
- [**Basic Usage**](./examples/basic-usage.md) - Simple implementation examples
|
|
50
|
-
- [**Advanced Scenarios**](./examples/advanced-scenarios.md) - Complex use cases
|
|
51
|
-
- [**Integration Examples**](./examples/integration-examples.md) - Framework-specific integrations
|
|
50
|
+
- [**Advanced Scenarios**](./examples/advanced-scenarios.md) - Complex use cases and framework integrations
|
|
52
51
|
|
|
53
52
|
### Production
|
|
54
53
|
|
|
@@ -92,27 +92,7 @@ await NativeUpdate.trackSignificantEvent(eventName: string);
|
|
|
92
92
|
|
|
93
93
|
## Events
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
Fired when review prompt is shown.
|
|
98
|
-
|
|
99
|
-
```typescript
|
|
100
|
-
NativeUpdate.addListener('reviewPromptDisplayed', (event) => {
|
|
101
|
-
console.log('Review prompt shown on:', event.platform);
|
|
102
|
-
analytics.track('review_prompt_displayed');
|
|
103
|
-
});
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
### reviewPromptDismissed
|
|
107
|
-
|
|
108
|
-
Fired when review prompt is dismissed.
|
|
109
|
-
|
|
110
|
-
```typescript
|
|
111
|
-
NativeUpdate.addListener('reviewPromptDismissed', (event) => {
|
|
112
|
-
console.log('Review prompt dismissed');
|
|
113
|
-
analytics.track('review_prompt_dismissed');
|
|
114
|
-
});
|
|
115
|
-
```
|
|
95
|
+
Note: App review events are handled natively by the platform's review system. The plugin does not expose custom events for review prompts as these are controlled by iOS StoreKit and Android Play Core.
|
|
116
96
|
|
|
117
97
|
## Platform Implementation
|
|
118
98
|
|
|
@@ -4,12 +4,12 @@ Complete API documentation for native app store update functionality.
|
|
|
4
4
|
|
|
5
5
|
## Methods
|
|
6
6
|
|
|
7
|
-
###
|
|
7
|
+
### getAppUpdateInfo()
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Get information about available app updates in the app store.
|
|
10
10
|
|
|
11
11
|
```typescript
|
|
12
|
-
const result = await NativeUpdate.
|
|
12
|
+
const result = await NativeUpdate.getAppUpdateInfo();
|
|
13
13
|
// Returns:
|
|
14
14
|
{
|
|
15
15
|
updateAvailable: boolean;
|
|
@@ -29,13 +29,13 @@ const result = await NativeUpdate.checkAppUpdate();
|
|
|
29
29
|
}
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
###
|
|
32
|
+
### performImmediateUpdate()
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
Perform an immediate (blocking) update. Android only - shows full-screen update UI.
|
|
35
35
|
|
|
36
36
|
```typescript
|
|
37
37
|
try {
|
|
38
|
-
await NativeUpdate.
|
|
38
|
+
await NativeUpdate.performImmediateUpdate();
|
|
39
39
|
// App will restart after update
|
|
40
40
|
} catch (error) {
|
|
41
41
|
// User cancelled or update failed
|
|
@@ -60,105 +60,20 @@ await NativeUpdate.completeFlexibleUpdate();
|
|
|
60
60
|
// App will restart
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
### getVersionInfo()
|
|
64
|
-
|
|
65
|
-
Get detailed version information.
|
|
66
|
-
|
|
67
|
-
```typescript
|
|
68
|
-
const info = await NativeUpdate.getVersionInfo();
|
|
69
|
-
// Returns:
|
|
70
|
-
{
|
|
71
|
-
currentVersion: string; // e.g., "1.2.3"
|
|
72
|
-
buildNumber: string; // e.g., "123"
|
|
73
|
-
packageName: string; // e.g., "com.example.app"
|
|
74
|
-
platform: 'ios' | 'android' | 'web';
|
|
75
|
-
availableVersion?: string; // From app store
|
|
76
|
-
minimumVersion?: string; // Minimum required version
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### isMinimumVersionMet()
|
|
81
|
-
|
|
82
|
-
Check if the app meets minimum version requirements.
|
|
83
|
-
|
|
84
|
-
```typescript
|
|
85
|
-
const result = await NativeUpdate.isMinimumVersionMet();
|
|
86
|
-
// Returns:
|
|
87
|
-
{
|
|
88
|
-
isMet: boolean;
|
|
89
|
-
currentVersion: string;
|
|
90
|
-
minimumVersion: string;
|
|
91
|
-
updateRequired: boolean;
|
|
92
|
-
}
|
|
93
|
-
```
|
|
94
|
-
|
|
95
63
|
### openAppStore()
|
|
96
64
|
|
|
97
65
|
Open the app store page for updates.
|
|
98
66
|
|
|
99
67
|
```typescript
|
|
100
|
-
await NativeUpdate.openAppStore(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
### getAppStoreUrl()
|
|
104
|
-
|
|
105
|
-
Get the app store URL without opening it.
|
|
106
|
-
|
|
107
|
-
```typescript
|
|
108
|
-
const result = await NativeUpdate.getAppStoreUrl();
|
|
109
|
-
// Returns:
|
|
110
|
-
{
|
|
111
|
-
url: string; // e.g., "https://apps.apple.com/app/id123456789"
|
|
112
|
-
platform: 'ios' | 'android' | 'web';
|
|
113
|
-
}
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### getUpdateInstallState()
|
|
117
|
-
|
|
118
|
-
Get the current install state of a flexible update. Android only.
|
|
119
|
-
|
|
120
|
-
```typescript
|
|
121
|
-
const state = await NativeUpdate.getUpdateInstallState();
|
|
122
|
-
// Returns:
|
|
123
|
-
{
|
|
124
|
-
installStatus: number; // Android InstallStatus code
|
|
125
|
-
bytesDownloaded: number;
|
|
126
|
-
totalBytesToDownload: number;
|
|
127
|
-
percentComplete: number;
|
|
128
|
-
}
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
## Events
|
|
132
|
-
|
|
133
|
-
### appUpdateStateChanged
|
|
134
|
-
|
|
135
|
-
Fired when app update state changes. Android only.
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
NativeUpdate.addListener('appUpdateStateChanged', (state) => {
|
|
139
|
-
console.log('Install status:', state.installStatus);
|
|
140
|
-
// InstallStatus codes:
|
|
141
|
-
// 0: Unknown
|
|
142
|
-
// 1: Pending
|
|
143
|
-
// 2: Downloading
|
|
144
|
-
// 3: Installing
|
|
145
|
-
// 4: Installed
|
|
146
|
-
// 5: Failed
|
|
147
|
-
// 6: Canceled
|
|
148
|
-
// 11: Downloaded
|
|
68
|
+
await NativeUpdate.openAppStore({
|
|
69
|
+
// Optional: specify app ID for iOS or package name for Android
|
|
70
|
+
appId: 'your-app-id'
|
|
149
71
|
});
|
|
150
72
|
```
|
|
151
73
|
|
|
152
|
-
|
|
74
|
+
## Events
|
|
153
75
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
```typescript
|
|
157
|
-
NativeUpdate.addListener('appUpdateProgress', (progress) => {
|
|
158
|
-
console.log(`Downloaded: ${progress.bytesDownloaded}/${progress.totalBytesToDownload}`);
|
|
159
|
-
console.log(`Progress: ${progress.percentComplete}%`);
|
|
160
|
-
});
|
|
161
|
-
```
|
|
76
|
+
Note: App update events are not directly exposed. Instead, use the `updateStateChanged` and `downloadProgress` events from the Live Update API when performing app updates. The native update process on Android and iOS is handled by the platform's native update mechanisms.
|
|
162
77
|
|
|
163
78
|
## Platform Differences
|
|
164
79
|
|
|
@@ -200,9 +115,9 @@ NativeUpdate.addListener('appUpdateProgress', (progress) => {
|
|
|
200
115
|
1. **Check for updates on app start**
|
|
201
116
|
```typescript
|
|
202
117
|
async function checkOnStart() {
|
|
203
|
-
const result = await NativeUpdate.
|
|
118
|
+
const result = await NativeUpdate.getAppUpdateInfo();
|
|
204
119
|
if (result.updateAvailable && result.updatePriority === 'IMMEDIATE') {
|
|
205
|
-
await NativeUpdate.
|
|
120
|
+
await NativeUpdate.performImmediateUpdate();
|
|
206
121
|
}
|
|
207
122
|
}
|
|
208
123
|
```
|
|
@@ -212,23 +127,16 @@ NativeUpdate.addListener('appUpdateProgress', (progress) => {
|
|
|
212
127
|
// Start download
|
|
213
128
|
await NativeUpdate.startFlexibleUpdate();
|
|
214
129
|
|
|
215
|
-
//
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
// Complete when ready
|
|
221
|
-
const stateListener = NativeUpdate.addListener('appUpdateStateChanged', (state) => {
|
|
222
|
-
if (state.installStatus === 11) { // Downloaded
|
|
223
|
-
showUpdateReadyPrompt();
|
|
224
|
-
}
|
|
225
|
-
});
|
|
130
|
+
// Note: Progress monitoring for native app updates is handled
|
|
131
|
+
// internally by the platform. For Android, the Play Core library
|
|
132
|
+
// shows its own UI. For custom progress tracking, use Live Updates
|
|
133
|
+
// instead of native app updates.
|
|
226
134
|
```
|
|
227
135
|
|
|
228
136
|
3. **Fallback for iOS**
|
|
229
137
|
```typescript
|
|
230
138
|
if (platform === 'ios') {
|
|
231
|
-
const result = await NativeUpdate.
|
|
139
|
+
const result = await NativeUpdate.getAppUpdateInfo();
|
|
232
140
|
if (result.updateAvailable) {
|
|
233
141
|
showUpdateDialog(() => {
|
|
234
142
|
NativeUpdate.openAppStore();
|