native-update 1.0.0 → 1.0.1
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 → NativeUpdate.podspec} +1 -1
- package/Readme.md +16 -16
- package/android/src/main/java/com/aoneahsan/nativeupdate/{CapacitorNativeUpdatePlugin.kt → NativeUpdatePlugin.kt} +2 -2
- package/dist/esm/core/errors.d.ts +6 -6
- package/dist/esm/core/errors.js +8 -8
- package/dist/esm/core/errors.js.map +1 -1
- package/dist/esm/core/logger.js +1 -1
- package/dist/esm/core/logger.js.map +1 -1
- package/dist/esm/core/plugin-manager.js +3 -3
- package/dist/esm/core/plugin-manager.js.map +1 -1
- package/dist/esm/definitions.d.ts +12 -14
- package/dist/esm/definitions.js +1 -0
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/index.d.ts +3 -3
- package/dist/esm/index.js +2 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/plugin.d.ts +3 -3
- package/dist/esm/plugin.js +13 -13
- package/dist/esm/plugin.js.map +1 -1
- package/dist/esm/web.d.ts +0 -1
- package/dist/esm/web.js +3 -3
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +1 -1
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.esm.js +1 -1
- package/dist/plugin.esm.js.map +1 -1
- package/dist/plugin.js +2 -2
- package/dist/plugin.js.map +1 -1
- package/docs/APP_REVIEW_GUIDE.md +12 -12
- package/docs/BUNDLE_SIGNING.md +4 -4
- package/docs/LIVE_UPDATES_GUIDE.md +48 -48
- package/docs/MIGRATION.md +10 -10
- package/docs/NATIVE_UPDATES_GUIDE.md +25 -25
- package/docs/QUICK_START.md +34 -34
- package/docs/README.md +5 -5
- package/docs/api/app-review-api.md +15 -15
- package/docs/api/app-update-api.md +18 -18
- package/docs/api/events-api.md +23 -23
- package/docs/api/live-update-api.md +20 -20
- package/docs/background-updates.md +18 -18
- package/docs/examples/advanced-scenarios.md +27 -27
- package/docs/examples/basic-usage.md +17 -17
- package/docs/features/app-reviews.md +13 -13
- package/docs/features/app-updates.md +21 -21
- package/docs/features/live-updates.md +32 -32
- package/docs/getting-started/configuration.md +8 -8
- package/docs/getting-started/installation.md +4 -4
- package/docs/getting-started/quick-start.md +28 -28
- package/docs/guides/deployment-guide.md +2 -2
- package/docs/guides/migration-from-codepush.md +5 -5
- package/docs/guides/testing-guide.md +17 -17
- package/docs/security/certificate-pinning.md +2 -2
- package/ios/Plugin/{CapacitorNativeUpdatePlugin.m → NativeUpdatePlugin.m} +1 -1
- package/package.json +2 -2
- /package/ios/Plugin/{CapacitorNativeUpdatePlugin.swift → NativeUpdatePlugin.swift} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Native App Updates Implementation Guide
|
|
2
2
|
|
|
3
|
-
This comprehensive guide explains how to implement Native App Updates (App Store and Google Play updates) in your Capacitor application using the
|
|
3
|
+
This comprehensive guide explains how to implement Native App Updates (App Store and Google Play updates) in your Capacitor application using the NativeUpdate plugin.
|
|
4
4
|
|
|
5
5
|
## Table of Contents
|
|
6
6
|
|
|
@@ -61,7 +61,7 @@ Native App Updates allow your app to:
|
|
|
61
61
|
### Installation
|
|
62
62
|
|
|
63
63
|
```bash
|
|
64
|
-
npm install
|
|
64
|
+
npm install native-update
|
|
65
65
|
npx cap sync
|
|
66
66
|
```
|
|
67
67
|
|
|
@@ -103,7 +103,7 @@ dependencies {
|
|
|
103
103
|
### Step 1: Basic Implementation
|
|
104
104
|
|
|
105
105
|
```typescript
|
|
106
|
-
import {
|
|
106
|
+
import { NativeUpdate } from 'native-update';
|
|
107
107
|
import { Capacitor } from '@capacitor/core';
|
|
108
108
|
|
|
109
109
|
export class NativeUpdateService {
|
|
@@ -113,7 +113,7 @@ export class NativeUpdateService {
|
|
|
113
113
|
const platform = Capacitor.getPlatform();
|
|
114
114
|
|
|
115
115
|
// Check for native app updates
|
|
116
|
-
const result = await
|
|
116
|
+
const result = await NativeUpdate.checkAppUpdate();
|
|
117
117
|
|
|
118
118
|
if (result.updateAvailable) {
|
|
119
119
|
console.log(`Update available: ${result.availableVersion}`);
|
|
@@ -144,7 +144,7 @@ export class AndroidImmediateUpdate {
|
|
|
144
144
|
async performImmediateUpdate() {
|
|
145
145
|
try {
|
|
146
146
|
// Start immediate update
|
|
147
|
-
const { started } = await
|
|
147
|
+
const { started } = await NativeUpdate.startImmediateUpdate();
|
|
148
148
|
|
|
149
149
|
if (started) {
|
|
150
150
|
// The app will be restarted automatically after update
|
|
@@ -187,10 +187,10 @@ export class AndroidFlexibleUpdate {
|
|
|
187
187
|
async performFlexibleUpdate() {
|
|
188
188
|
try {
|
|
189
189
|
// Start flexible update
|
|
190
|
-
await
|
|
190
|
+
await NativeUpdate.startFlexibleUpdate();
|
|
191
191
|
|
|
192
192
|
// Listen for download progress
|
|
193
|
-
|
|
193
|
+
NativeUpdate.addListener(
|
|
194
194
|
'onAppUpdateDownloadProgress',
|
|
195
195
|
(progress) => {
|
|
196
196
|
console.log(
|
|
@@ -201,7 +201,7 @@ export class AndroidFlexibleUpdate {
|
|
|
201
201
|
);
|
|
202
202
|
|
|
203
203
|
// Listen for download completion
|
|
204
|
-
|
|
204
|
+
NativeUpdate.addListener('onAppUpdateDownloaded', () => {
|
|
205
205
|
console.log('Update downloaded');
|
|
206
206
|
this.updateDownloaded = true;
|
|
207
207
|
this.showInstallPrompt();
|
|
@@ -237,7 +237,7 @@ export class AndroidFlexibleUpdate {
|
|
|
237
237
|
|
|
238
238
|
async completeFlexibleUpdate() {
|
|
239
239
|
try {
|
|
240
|
-
await
|
|
240
|
+
await NativeUpdate.completeFlexibleUpdate();
|
|
241
241
|
// App will restart with new version
|
|
242
242
|
} catch (error) {
|
|
243
243
|
console.error('Failed to complete update:', error);
|
|
@@ -261,7 +261,7 @@ export class AndroidFlexibleUpdate {
|
|
|
261
261
|
export class iOSAppStoreUpdate {
|
|
262
262
|
async checkAndPromptUpdate() {
|
|
263
263
|
try {
|
|
264
|
-
const result = await
|
|
264
|
+
const result = await NativeUpdate.checkAppUpdate();
|
|
265
265
|
|
|
266
266
|
if (result.updateAvailable) {
|
|
267
267
|
await this.showiOSUpdateDialog(result);
|
|
@@ -293,7 +293,7 @@ export class iOSAppStoreUpdate {
|
|
|
293
293
|
|
|
294
294
|
async openAppStore() {
|
|
295
295
|
try {
|
|
296
|
-
await
|
|
296
|
+
await NativeUpdate.openAppStore();
|
|
297
297
|
} catch (error) {
|
|
298
298
|
// Fallback to browser
|
|
299
299
|
const appStoreUrl = `https://apps.apple.com/app/id${YOUR_APP_STORE_ID}`;
|
|
@@ -307,14 +307,14 @@ export class iOSAppStoreUpdate {
|
|
|
307
307
|
|
|
308
308
|
```typescript
|
|
309
309
|
import { Capacitor } from '@capacitor/core';
|
|
310
|
-
import {
|
|
310
|
+
import { NativeUpdate } from 'native-update';
|
|
311
311
|
|
|
312
312
|
export class UnifiedUpdateService {
|
|
313
313
|
private platform = Capacitor.getPlatform();
|
|
314
314
|
|
|
315
315
|
async checkAndUpdateApp() {
|
|
316
316
|
try {
|
|
317
|
-
const updateInfo = await
|
|
317
|
+
const updateInfo = await NativeUpdate.checkAppUpdate();
|
|
318
318
|
|
|
319
319
|
if (!updateInfo.updateAvailable) {
|
|
320
320
|
console.log('App is up to date');
|
|
@@ -361,7 +361,7 @@ export class UnifiedUpdateService {
|
|
|
361
361
|
title: 'Update Available',
|
|
362
362
|
message: `Version ${updateInfo.availableVersion} is available on the App Store.`,
|
|
363
363
|
mandatory: false,
|
|
364
|
-
action: () =>
|
|
364
|
+
action: () => NativeUpdate.openAppStore(),
|
|
365
365
|
});
|
|
366
366
|
}
|
|
367
367
|
|
|
@@ -411,7 +411,7 @@ export class UpdateStatusManager {
|
|
|
411
411
|
|
|
412
412
|
private setupUpdateListeners() {
|
|
413
413
|
// Installation status
|
|
414
|
-
|
|
414
|
+
NativeUpdate.addListener('onAppUpdateInstallStatus', (status) => {
|
|
415
415
|
switch (status.status) {
|
|
416
416
|
case 'PENDING':
|
|
417
417
|
console.log('Update pending');
|
|
@@ -437,7 +437,7 @@ export class UpdateStatusManager {
|
|
|
437
437
|
});
|
|
438
438
|
|
|
439
439
|
// Download progress (Android flexible updates)
|
|
440
|
-
|
|
440
|
+
NativeUpdate.addListener(
|
|
441
441
|
'onAppUpdateDownloadProgress',
|
|
442
442
|
(progress) => {
|
|
443
443
|
const percent = Math.round(
|
|
@@ -534,7 +534,7 @@ export class UpdateUIService {
|
|
|
534
534
|
```typescript
|
|
535
535
|
export class SmartUpdateScheduler {
|
|
536
536
|
async scheduleUpdate() {
|
|
537
|
-
const updateInfo = await
|
|
537
|
+
const updateInfo = await NativeUpdate.checkAppUpdate();
|
|
538
538
|
|
|
539
539
|
if (!updateInfo.updateAvailable) return;
|
|
540
540
|
|
|
@@ -573,7 +573,7 @@ export class SmartUpdateScheduler {
|
|
|
573
573
|
|
|
574
574
|
```typescript
|
|
575
575
|
// Enable internal app sharing for testing
|
|
576
|
-
await
|
|
576
|
+
await NativeUpdate.enableDebugMode({
|
|
577
577
|
enabled: true,
|
|
578
578
|
testMode: 'internal-test',
|
|
579
579
|
});
|
|
@@ -583,13 +583,13 @@ await CapacitorNativeUpdate.enableDebugMode({
|
|
|
583
583
|
|
|
584
584
|
```typescript
|
|
585
585
|
// Test immediate update
|
|
586
|
-
await
|
|
586
|
+
await NativeUpdate.simulateUpdate({
|
|
587
587
|
type: 'immediate',
|
|
588
588
|
version: '2.0.0',
|
|
589
589
|
});
|
|
590
590
|
|
|
591
591
|
// Test flexible update
|
|
592
|
-
await
|
|
592
|
+
await NativeUpdate.simulateUpdate({
|
|
593
593
|
type: 'flexible',
|
|
594
594
|
version: '1.1.0',
|
|
595
595
|
});
|
|
@@ -626,7 +626,7 @@ await CapacitorNativeUpdate.simulateUpdate({
|
|
|
626
626
|
|
|
627
627
|
```typescript
|
|
628
628
|
// Debug update detection
|
|
629
|
-
const debug = await
|
|
629
|
+
const debug = await NativeUpdate.getDebugInfo();
|
|
630
630
|
console.log('Debug info:', {
|
|
631
631
|
currentVersion: debug.currentVersion,
|
|
632
632
|
packageName: debug.packageName,
|
|
@@ -639,11 +639,11 @@ console.log('Debug info:', {
|
|
|
639
639
|
|
|
640
640
|
```typescript
|
|
641
641
|
// Check update state
|
|
642
|
-
const state = await
|
|
642
|
+
const state = await NativeUpdate.getUpdateState();
|
|
643
643
|
if (state.status === 'FAILED') {
|
|
644
644
|
// Clear update data and retry
|
|
645
|
-
await
|
|
646
|
-
await
|
|
645
|
+
await NativeUpdate.clearUpdateData();
|
|
646
|
+
await NativeUpdate.checkAppUpdate();
|
|
647
647
|
}
|
|
648
648
|
```
|
|
649
649
|
|
|
@@ -651,7 +651,7 @@ if (state.status === 'FAILED') {
|
|
|
651
651
|
|
|
652
652
|
```typescript
|
|
653
653
|
// Verify App Store ID configuration
|
|
654
|
-
const config = await
|
|
654
|
+
const config = await NativeUpdate.getConfiguration();
|
|
655
655
|
console.log('App Store ID:', config.appStoreId);
|
|
656
656
|
|
|
657
657
|
// Manual fallback
|
package/docs/QUICK_START.md
CHANGED
|
@@ -10,7 +10,7 @@ Get up and running with Capacitor Native Update in 5 minutes! This guide covers
|
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
12
|
# Install the plugin
|
|
13
|
-
npm install
|
|
13
|
+
npm install native-update
|
|
14
14
|
|
|
15
15
|
# Sync with native projects
|
|
16
16
|
npx cap sync
|
|
@@ -27,7 +27,7 @@ npx cap sync
|
|
|
27
27
|
"appId": "com.example.app",
|
|
28
28
|
"appName": "MyApp",
|
|
29
29
|
"plugins": {
|
|
30
|
-
"
|
|
30
|
+
"NativeUpdate": {
|
|
31
31
|
"updateUrl": "https://updates.example.com/api/v1",
|
|
32
32
|
"autoCheck": true,
|
|
33
33
|
"appStoreId": "123456789"
|
|
@@ -39,7 +39,7 @@ npx cap sync
|
|
|
39
39
|
### 2. Import and Initialize
|
|
40
40
|
|
|
41
41
|
```typescript
|
|
42
|
-
import {
|
|
42
|
+
import { NativeUpdate } from 'native-update';
|
|
43
43
|
|
|
44
44
|
// Initialize on app start
|
|
45
45
|
export class App {
|
|
@@ -65,14 +65,14 @@ Push updates without app store review!
|
|
|
65
65
|
### Basic Implementation
|
|
66
66
|
|
|
67
67
|
```typescript
|
|
68
|
-
import {
|
|
68
|
+
import { NativeUpdate } from 'native-update';
|
|
69
69
|
|
|
70
70
|
export class LiveUpdateService {
|
|
71
71
|
async checkAndApplyUpdates() {
|
|
72
72
|
try {
|
|
73
73
|
// 1. Check for updates
|
|
74
74
|
const { available, version } =
|
|
75
|
-
await
|
|
75
|
+
await NativeUpdate.checkForUpdate();
|
|
76
76
|
|
|
77
77
|
if (!available) {
|
|
78
78
|
console.log('No updates available');
|
|
@@ -82,14 +82,14 @@ export class LiveUpdateService {
|
|
|
82
82
|
console.log(`Update ${version} available!`);
|
|
83
83
|
|
|
84
84
|
// 2. Download the update
|
|
85
|
-
await
|
|
85
|
+
await NativeUpdate.downloadUpdate({
|
|
86
86
|
onProgress: (progress) => {
|
|
87
87
|
console.log(`Download: ${progress.percent}%`);
|
|
88
88
|
},
|
|
89
89
|
});
|
|
90
90
|
|
|
91
91
|
// 3. Apply the update (app will restart)
|
|
92
|
-
await
|
|
92
|
+
await NativeUpdate.applyUpdate();
|
|
93
93
|
} catch (error) {
|
|
94
94
|
console.error('Update failed:', error);
|
|
95
95
|
}
|
|
@@ -108,7 +108,7 @@ export class UpdateUIService {
|
|
|
108
108
|
|
|
109
109
|
async checkForUpdatesWithUI() {
|
|
110
110
|
const { available, version, notes } =
|
|
111
|
-
await
|
|
111
|
+
await NativeUpdate.checkForUpdate();
|
|
112
112
|
|
|
113
113
|
if (!available) return;
|
|
114
114
|
|
|
@@ -135,14 +135,14 @@ export class UpdateUIService {
|
|
|
135
135
|
await loading.present();
|
|
136
136
|
|
|
137
137
|
try {
|
|
138
|
-
await
|
|
138
|
+
await NativeUpdate.downloadUpdate({
|
|
139
139
|
onProgress: (progress) => {
|
|
140
140
|
loading.message = `Downloading: ${Math.round(progress.percent)}%`;
|
|
141
141
|
},
|
|
142
142
|
});
|
|
143
143
|
|
|
144
144
|
loading.message = 'Installing...';
|
|
145
|
-
await
|
|
145
|
+
await NativeUpdate.applyUpdate();
|
|
146
146
|
} catch (error) {
|
|
147
147
|
await loading.dismiss();
|
|
148
148
|
// Show error
|
|
@@ -179,7 +179,7 @@ Check for app store updates and install them!
|
|
|
179
179
|
export class NativeUpdateService {
|
|
180
180
|
async checkForAppStoreUpdates() {
|
|
181
181
|
try {
|
|
182
|
-
const result = await
|
|
182
|
+
const result = await NativeUpdate.checkAppUpdate();
|
|
183
183
|
|
|
184
184
|
if (!result.updateAvailable) {
|
|
185
185
|
console.log('App is up to date');
|
|
@@ -200,10 +200,10 @@ export class NativeUpdateService {
|
|
|
200
200
|
private async handleAndroidUpdate(result: any) {
|
|
201
201
|
if (result.immediateUpdateAllowed) {
|
|
202
202
|
// Critical update - must install
|
|
203
|
-
await
|
|
203
|
+
await NativeUpdate.startImmediateUpdate();
|
|
204
204
|
} else {
|
|
205
205
|
// Optional update - download in background
|
|
206
|
-
await
|
|
206
|
+
await NativeUpdate.startFlexibleUpdate();
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
209
|
|
|
@@ -216,7 +216,7 @@ export class NativeUpdateService {
|
|
|
216
216
|
{ text: 'Later', role: 'cancel' },
|
|
217
217
|
{
|
|
218
218
|
text: 'Update',
|
|
219
|
-
handler: () =>
|
|
219
|
+
handler: () => NativeUpdate.openAppStore(),
|
|
220
220
|
},
|
|
221
221
|
],
|
|
222
222
|
});
|
|
@@ -233,10 +233,10 @@ export class AndroidUpdateProgress {
|
|
|
233
233
|
|
|
234
234
|
async startFlexibleUpdate() {
|
|
235
235
|
// Start download
|
|
236
|
-
await
|
|
236
|
+
await NativeUpdate.startFlexibleUpdate();
|
|
237
237
|
|
|
238
238
|
// Track progress
|
|
239
|
-
|
|
239
|
+
NativeUpdate.addListener(
|
|
240
240
|
'onAppUpdateDownloadProgress',
|
|
241
241
|
(progress) => {
|
|
242
242
|
this.downloadProgress = Math.round(
|
|
@@ -246,7 +246,7 @@ export class AndroidUpdateProgress {
|
|
|
246
246
|
);
|
|
247
247
|
|
|
248
248
|
// Handle completion
|
|
249
|
-
|
|
249
|
+
NativeUpdate.addListener('onAppUpdateDownloaded', async () => {
|
|
250
250
|
const alert = await this.alertController.create({
|
|
251
251
|
header: 'Update Ready',
|
|
252
252
|
message: 'Update has been downloaded. Install now?',
|
|
@@ -254,7 +254,7 @@ export class AndroidUpdateProgress {
|
|
|
254
254
|
{ text: 'Later' },
|
|
255
255
|
{
|
|
256
256
|
text: 'Install',
|
|
257
|
-
handler: () =>
|
|
257
|
+
handler: () => NativeUpdate.completeFlexibleUpdate(),
|
|
258
258
|
},
|
|
259
259
|
],
|
|
260
260
|
});
|
|
@@ -274,7 +274,7 @@ Request ratings without users leaving your app!
|
|
|
274
274
|
export class AppReviewService {
|
|
275
275
|
async requestReview() {
|
|
276
276
|
try {
|
|
277
|
-
const result = await
|
|
277
|
+
const result = await NativeUpdate.requestReview();
|
|
278
278
|
|
|
279
279
|
if (result.displayed) {
|
|
280
280
|
console.log('Review prompt shown');
|
|
@@ -307,7 +307,7 @@ export class SmartReviewService {
|
|
|
307
307
|
const enjoying = await this.askIfEnjoying();
|
|
308
308
|
|
|
309
309
|
if (enjoying) {
|
|
310
|
-
await
|
|
310
|
+
await NativeUpdate.requestReview();
|
|
311
311
|
} else {
|
|
312
312
|
await this.askForFeedback();
|
|
313
313
|
}
|
|
@@ -388,7 +388,7 @@ Here's everything working together:
|
|
|
388
388
|
|
|
389
389
|
```typescript
|
|
390
390
|
import { Component, OnInit } from '@angular/core';
|
|
391
|
-
import {
|
|
391
|
+
import { NativeUpdate } from 'native-update';
|
|
392
392
|
import { Capacitor } from '@capacitor/core';
|
|
393
393
|
|
|
394
394
|
@Component({
|
|
@@ -422,11 +422,11 @@ export class AppComponent implements OnInit {
|
|
|
422
422
|
// Live Updates
|
|
423
423
|
private async checkLiveUpdates() {
|
|
424
424
|
try {
|
|
425
|
-
const { available } = await
|
|
425
|
+
const { available } = await NativeUpdate.checkForUpdate();
|
|
426
426
|
|
|
427
427
|
if (available) {
|
|
428
428
|
// Auto-download in background
|
|
429
|
-
await
|
|
429
|
+
await NativeUpdate.downloadUpdate();
|
|
430
430
|
|
|
431
431
|
// Notify user
|
|
432
432
|
const toast = await this.toastCtrl.create({
|
|
@@ -435,7 +435,7 @@ export class AppComponent implements OnInit {
|
|
|
435
435
|
buttons: [
|
|
436
436
|
{
|
|
437
437
|
text: 'Restart',
|
|
438
|
-
handler: () =>
|
|
438
|
+
handler: () => NativeUpdate.applyUpdate(),
|
|
439
439
|
},
|
|
440
440
|
],
|
|
441
441
|
});
|
|
@@ -462,12 +462,12 @@ export class AppComponent implements OnInit {
|
|
|
462
462
|
|
|
463
463
|
private async checkNativeUpdates() {
|
|
464
464
|
try {
|
|
465
|
-
const result = await
|
|
465
|
+
const result = await NativeUpdate.checkAppUpdate();
|
|
466
466
|
|
|
467
467
|
if (result.updateAvailable && result.flexibleUpdateAllowed) {
|
|
468
468
|
// Start background download for Android
|
|
469
469
|
if (Capacitor.getPlatform() === 'android') {
|
|
470
|
-
await
|
|
470
|
+
await NativeUpdate.startFlexibleUpdate();
|
|
471
471
|
}
|
|
472
472
|
}
|
|
473
473
|
} catch (error) {
|
|
@@ -492,7 +492,7 @@ export class AppComponent implements OnInit {
|
|
|
492
492
|
const canAsk = await this.canAskForReview();
|
|
493
493
|
|
|
494
494
|
if (canAsk) {
|
|
495
|
-
await
|
|
495
|
+
await NativeUpdate.requestReview();
|
|
496
496
|
await this.markReviewRequested();
|
|
497
497
|
}
|
|
498
498
|
}
|
|
@@ -545,10 +545,10 @@ curl -X POST http://localhost:3000/api/v1/bundles \
|
|
|
545
545
|
|
|
546
546
|
```typescript
|
|
547
547
|
// Enable debug mode
|
|
548
|
-
await
|
|
548
|
+
await NativeUpdate.setReviewDebugMode({ enabled: true });
|
|
549
549
|
|
|
550
550
|
// Force show review (debug only)
|
|
551
|
-
await
|
|
551
|
+
await NativeUpdate.requestReview({ force: true });
|
|
552
552
|
```
|
|
553
553
|
|
|
554
554
|
## What's Next?
|
|
@@ -578,10 +578,10 @@ Now that you have the basics working:
|
|
|
578
578
|
|
|
579
579
|
```typescript
|
|
580
580
|
// Enable debug logging
|
|
581
|
-
await
|
|
581
|
+
await NativeUpdate.setDebugMode({ enabled: true });
|
|
582
582
|
|
|
583
583
|
// Check configuration
|
|
584
|
-
const config = await
|
|
584
|
+
const config = await NativeUpdate.getConfiguration();
|
|
585
585
|
console.log('Update URL:', config.updateUrl);
|
|
586
586
|
```
|
|
587
587
|
|
|
@@ -599,8 +599,8 @@ console.log('Update URL:', config.updateUrl);
|
|
|
599
599
|
|
|
600
600
|
## Support
|
|
601
601
|
|
|
602
|
-
- 📖 [Documentation](https://github.com/aoneahsan/
|
|
603
|
-
- 🐛 [Issue Tracker](https://github.com/aoneahsan/
|
|
604
|
-
- 💬 [Discussions](https://github.com/aoneahsan/
|
|
602
|
+
- 📖 [Documentation](https://github.com/aoneahsan/native-update)
|
|
603
|
+
- 🐛 [Issue Tracker](https://github.com/aoneahsan/native-update/issues)
|
|
604
|
+
- 💬 [Discussions](https://github.com/aoneahsan/native-update/discussions)
|
|
605
605
|
|
|
606
606
|
Happy updating! 🚀
|
package/docs/README.md
CHANGED
|
@@ -56,9 +56,9 @@ Created by **Ahsan Mahmood** and open-sourced for the developer community, this
|
|
|
56
56
|
|
|
57
57
|
## 🚀 Quick Links
|
|
58
58
|
|
|
59
|
-
- **NPM Package**: [
|
|
60
|
-
- **GitHub Repository**: [aoneahsan/
|
|
61
|
-
- **Issue Tracker**: [GitHub Issues](https://github.com/aoneahsan/
|
|
59
|
+
- **NPM Package**: [native-update](https://www.npmjs.com/package/native-update)
|
|
60
|
+
- **GitHub Repository**: [aoneahsan/native-update](https://github.com/aoneahsan/native-update)
|
|
61
|
+
- **Issue Tracker**: [GitHub Issues](https://github.com/aoneahsan/native-update/issues)
|
|
62
62
|
- **Author**: [Ahsan Mahmood](https://aoneahsan.com)
|
|
63
63
|
|
|
64
64
|
## 💡 Key Features
|
|
@@ -92,11 +92,11 @@ Consistent API across iOS, Android, and Web platforms with platform-specific opt
|
|
|
92
92
|
|
|
93
93
|
## 🤝 Contributing
|
|
94
94
|
|
|
95
|
-
We welcome contributions from the community! Please see our [Contributing Guide](https://github.com/aoneahsan/
|
|
95
|
+
We welcome contributions from the community! Please see our [Contributing Guide](https://github.com/aoneahsan/native-update/blob/main/CONTRIBUTING.md) for details.
|
|
96
96
|
|
|
97
97
|
## 📄 License
|
|
98
98
|
|
|
99
|
-
This project is licensed under the MIT License. See the [LICENSE](https://github.com/aoneahsan/
|
|
99
|
+
This project is licensed under the MIT License. See the [LICENSE](https://github.com/aoneahsan/native-update/blob/main/LICENSE) file for details.
|
|
100
100
|
|
|
101
101
|
## 👨💻 About the Author
|
|
102
102
|
|
|
@@ -9,7 +9,7 @@ Complete API documentation for in-app review functionality.
|
|
|
9
9
|
Request an in-app review dialog.
|
|
10
10
|
|
|
11
11
|
```typescript
|
|
12
|
-
const result = await
|
|
12
|
+
const result = await NativeUpdate.requestReview({
|
|
13
13
|
force?: boolean; // Bypass rate limiting (testing only)
|
|
14
14
|
});
|
|
15
15
|
// Returns:
|
|
@@ -27,7 +27,7 @@ const result = await CapacitorNativeUpdate.requestReview({
|
|
|
27
27
|
Check if a review can be requested (respects rate limits).
|
|
28
28
|
|
|
29
29
|
```typescript
|
|
30
|
-
const result = await
|
|
30
|
+
const result = await NativeUpdate.canRequestReview();
|
|
31
31
|
// Returns:
|
|
32
32
|
{
|
|
33
33
|
canRequest: boolean;
|
|
@@ -43,7 +43,7 @@ const result = await CapacitorNativeUpdate.canRequestReview();
|
|
|
43
43
|
Open the app store review page directly.
|
|
44
44
|
|
|
45
45
|
```typescript
|
|
46
|
-
await
|
|
46
|
+
await NativeUpdate.openStoreReview();
|
|
47
47
|
// Opens app store with review section focused
|
|
48
48
|
```
|
|
49
49
|
|
|
@@ -52,7 +52,7 @@ await CapacitorNativeUpdate.openStoreReview();
|
|
|
52
52
|
Get the store review URL without opening it.
|
|
53
53
|
|
|
54
54
|
```typescript
|
|
55
|
-
const result = await
|
|
55
|
+
const result = await NativeUpdate.getStoreReviewUrl();
|
|
56
56
|
// Returns:
|
|
57
57
|
{
|
|
58
58
|
url: string; // Direct review URL
|
|
@@ -65,7 +65,7 @@ const result = await CapacitorNativeUpdate.getStoreReviewUrl();
|
|
|
65
65
|
Reset review request history (testing only).
|
|
66
66
|
|
|
67
67
|
```typescript
|
|
68
|
-
await
|
|
68
|
+
await NativeUpdate.resetReviewPrompts();
|
|
69
69
|
```
|
|
70
70
|
|
|
71
71
|
### setReviewConditions(conditions)
|
|
@@ -73,7 +73,7 @@ await CapacitorNativeUpdate.resetReviewPrompts();
|
|
|
73
73
|
Set conditions for when to show review prompts.
|
|
74
74
|
|
|
75
75
|
```typescript
|
|
76
|
-
await
|
|
76
|
+
await NativeUpdate.setReviewConditions({
|
|
77
77
|
minimumDaysSinceInstall?: number; // Default: 3
|
|
78
78
|
minimumDaysSinceLastPrompt?: number; // Default: 90
|
|
79
79
|
minimumAppLaunches?: number; // Default: 5
|
|
@@ -86,7 +86,7 @@ await CapacitorNativeUpdate.setReviewConditions({
|
|
|
86
86
|
Track significant events for review timing.
|
|
87
87
|
|
|
88
88
|
```typescript
|
|
89
|
-
await
|
|
89
|
+
await NativeUpdate.trackSignificantEvent(eventName: string);
|
|
90
90
|
// Examples: 'purchase_completed', 'level_completed', 'content_shared'
|
|
91
91
|
```
|
|
92
92
|
|
|
@@ -97,7 +97,7 @@ await CapacitorNativeUpdate.trackSignificantEvent(eventName: string);
|
|
|
97
97
|
Fired when review prompt is shown.
|
|
98
98
|
|
|
99
99
|
```typescript
|
|
100
|
-
|
|
100
|
+
NativeUpdate.addListener('reviewPromptDisplayed', (event) => {
|
|
101
101
|
console.log('Review prompt shown on:', event.platform);
|
|
102
102
|
analytics.track('review_prompt_displayed');
|
|
103
103
|
});
|
|
@@ -108,7 +108,7 @@ CapacitorNativeUpdate.addListener('reviewPromptDisplayed', (event) => {
|
|
|
108
108
|
Fired when review prompt is dismissed.
|
|
109
109
|
|
|
110
110
|
```typescript
|
|
111
|
-
|
|
111
|
+
NativeUpdate.addListener('reviewPromptDismissed', (event) => {
|
|
112
112
|
console.log('Review prompt dismissed');
|
|
113
113
|
analytics.track('review_prompt_dismissed');
|
|
114
114
|
});
|
|
@@ -151,9 +151,9 @@ async function onPurchaseComplete() {
|
|
|
151
151
|
|
|
152
152
|
// Wait a bit, then request review
|
|
153
153
|
setTimeout(async () => {
|
|
154
|
-
const { canRequest } = await
|
|
154
|
+
const { canRequest } = await NativeUpdate.canRequestReview();
|
|
155
155
|
if (canRequest) {
|
|
156
|
-
await
|
|
156
|
+
await NativeUpdate.requestReview();
|
|
157
157
|
}
|
|
158
158
|
}, 2000);
|
|
159
159
|
}
|
|
@@ -173,7 +173,7 @@ const SIGNIFICANT_EVENTS = [
|
|
|
173
173
|
|
|
174
174
|
async function trackUserAction(action: string) {
|
|
175
175
|
if (SIGNIFICANT_EVENTS.includes(action)) {
|
|
176
|
-
await
|
|
176
|
+
await NativeUpdate.trackSignificantEvent(action);
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
179
|
```
|
|
@@ -182,7 +182,7 @@ async function trackUserAction(action: string) {
|
|
|
182
182
|
|
|
183
183
|
```typescript
|
|
184
184
|
// Configure smart conditions
|
|
185
|
-
await
|
|
185
|
+
await NativeUpdate.setReviewConditions({
|
|
186
186
|
minimumDaysSinceInstall: 7, // Week after install
|
|
187
187
|
minimumDaysSinceLastPrompt: 120, // 4 months between
|
|
188
188
|
minimumAppLaunches: 10, // Regular user
|
|
@@ -195,13 +195,13 @@ await CapacitorNativeUpdate.setReviewConditions({
|
|
|
195
195
|
```typescript
|
|
196
196
|
async function requestReviewSmart() {
|
|
197
197
|
try {
|
|
198
|
-
const { displayed } = await
|
|
198
|
+
const { displayed } = await NativeUpdate.requestReview();
|
|
199
199
|
|
|
200
200
|
if (!displayed) {
|
|
201
201
|
// Fallback: Show custom UI with store link
|
|
202
202
|
const response = await showCustomReviewDialog();
|
|
203
203
|
if (response === 'yes') {
|
|
204
|
-
await
|
|
204
|
+
await NativeUpdate.openStoreReview();
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
} catch (error) {
|