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,139 @@
|
|
|
1
|
+
# Remaining Features for Production Readiness
|
|
2
|
+
|
|
3
|
+
This document tracks all remaining work needed to make this package fully production-ready.
|
|
4
|
+
|
|
5
|
+
## ✅ Recently Completed
|
|
6
|
+
|
|
7
|
+
### Testing & Tools
|
|
8
|
+
- [x] Basic test structure with Vitest
|
|
9
|
+
- [x] Bundle creation utility (`tools/bundle-creator.js`)
|
|
10
|
+
- [x] Bundle signing tool (`tools/bundle-signer.js`)
|
|
11
|
+
- [x] Minimal backend server template
|
|
12
|
+
|
|
13
|
+
## 🔴 Critical Missing Components
|
|
14
|
+
|
|
15
|
+
### 1. Backend Infrastructure
|
|
16
|
+
- [ ] Production-grade update server
|
|
17
|
+
- [ ] Database integration (PostgreSQL/MongoDB)
|
|
18
|
+
- [ ] CDN integration for bundle distribution
|
|
19
|
+
- [ ] API authentication and rate limiting
|
|
20
|
+
- [ ] Admin dashboard for managing updates
|
|
21
|
+
- [ ] Monitoring and analytics
|
|
22
|
+
|
|
23
|
+
### 2. Native Platform Implementation
|
|
24
|
+
- [ ] Complete iOS implementation verification
|
|
25
|
+
- [ ] Complete Android implementation verification
|
|
26
|
+
- [ ] Platform-specific error handling
|
|
27
|
+
- [ ] Background update services
|
|
28
|
+
- [ ] Native UI components for updates
|
|
29
|
+
- [ ] App store integration testing
|
|
30
|
+
|
|
31
|
+
### 3. Testing Suite
|
|
32
|
+
- [ ] Complete unit tests for TypeScript code
|
|
33
|
+
- [ ] Unit tests for iOS native code
|
|
34
|
+
- [ ] Unit tests for Android native code
|
|
35
|
+
- [ ] Integration tests across platforms
|
|
36
|
+
- [ ] E2E testing scenarios
|
|
37
|
+
- [ ] Security vulnerability testing
|
|
38
|
+
- [ ] Performance benchmarking
|
|
39
|
+
|
|
40
|
+
### 4. Security Implementation
|
|
41
|
+
- [ ] Client-side signature verification
|
|
42
|
+
- [ ] Certificate pinning
|
|
43
|
+
- [ ] Encryption for sensitive data
|
|
44
|
+
- [ ] Secure key storage on device
|
|
45
|
+
- [ ] Anti-tampering measures
|
|
46
|
+
|
|
47
|
+
### 5. Developer Tools
|
|
48
|
+
- [ ] Complete CLI package
|
|
49
|
+
- [ ] Version management system
|
|
50
|
+
- [ ] Migration scripts
|
|
51
|
+
- [ ] Debug utilities
|
|
52
|
+
- [ ] Production deployment tools
|
|
53
|
+
|
|
54
|
+
## 🟡 Enhancement Features
|
|
55
|
+
|
|
56
|
+
### 1. Advanced Update Features
|
|
57
|
+
- [ ] Delta updates implementation
|
|
58
|
+
- [ ] Partial bundle updates
|
|
59
|
+
- [ ] Update rollback mechanism
|
|
60
|
+
- [ ] A/B testing support
|
|
61
|
+
- [ ] Staged rollouts
|
|
62
|
+
- [ ] Update scheduling
|
|
63
|
+
|
|
64
|
+
### 2. Monitoring & Analytics
|
|
65
|
+
- [ ] Update success tracking
|
|
66
|
+
- [ ] Error reporting system
|
|
67
|
+
- [ ] Performance metrics
|
|
68
|
+
- [ ] User adoption tracking
|
|
69
|
+
- [ ] Crash reporting integration
|
|
70
|
+
- [ ] Update analytics dashboard
|
|
71
|
+
|
|
72
|
+
### 3. Developer Experience
|
|
73
|
+
- [ ] Comprehensive error messages
|
|
74
|
+
- [ ] Better TypeScript types
|
|
75
|
+
- [ ] Framework-specific adapters
|
|
76
|
+
- [ ] Plugin hooks system
|
|
77
|
+
- [ ] Event system improvements
|
|
78
|
+
- [ ] Debug mode enhancements
|
|
79
|
+
|
|
80
|
+
## 🟢 Documentation & Examples
|
|
81
|
+
|
|
82
|
+
### 1. Missing Documentation
|
|
83
|
+
- [ ] Complete API reference
|
|
84
|
+
- [ ] Platform-specific guides
|
|
85
|
+
- [ ] Troubleshooting guide
|
|
86
|
+
- [ ] Performance optimization guide
|
|
87
|
+
- [ ] Security implementation guide
|
|
88
|
+
- [ ] Migration from v1 guide
|
|
89
|
+
|
|
90
|
+
### 2. Example Implementations
|
|
91
|
+
- [ ] React example app
|
|
92
|
+
- [ ] Vue example app
|
|
93
|
+
- [ ] Angular example app
|
|
94
|
+
- [ ] Backend server examples (Node, Python, Java)
|
|
95
|
+
- [ ] CI/CD integration examples
|
|
96
|
+
- [ ] Production deployment guide
|
|
97
|
+
|
|
98
|
+
### 3. Video Tutorials
|
|
99
|
+
- [ ] Getting started video
|
|
100
|
+
- [ ] Backend setup tutorial
|
|
101
|
+
- [ ] Security implementation
|
|
102
|
+
- [ ] Production deployment
|
|
103
|
+
- [ ] Troubleshooting common issues
|
|
104
|
+
|
|
105
|
+
## 📊 Implementation Priority
|
|
106
|
+
|
|
107
|
+
### Phase 1: Core Functionality (2-3 months)
|
|
108
|
+
1. Complete native implementations
|
|
109
|
+
2. Basic backend server
|
|
110
|
+
3. Essential testing
|
|
111
|
+
4. Security basics
|
|
112
|
+
|
|
113
|
+
### Phase 2: Production Features (1-2 months)
|
|
114
|
+
1. Advanced update features
|
|
115
|
+
2. Monitoring system
|
|
116
|
+
3. Developer tools
|
|
117
|
+
4. Performance optimization
|
|
118
|
+
|
|
119
|
+
### Phase 3: Polish & Scale (1-2 months)
|
|
120
|
+
1. Complete documentation
|
|
121
|
+
2. Example apps
|
|
122
|
+
3. Enterprise features
|
|
123
|
+
4. Community tools
|
|
124
|
+
|
|
125
|
+
## 🎯 Next Steps
|
|
126
|
+
|
|
127
|
+
1. **Verify Native Code**: Test iOS and Android implementations
|
|
128
|
+
2. **Build Minimal Backend**: Create basic update server
|
|
129
|
+
3. **Add Core Tests**: Unit tests for critical paths
|
|
130
|
+
4. **Implement Security**: Basic signing and verification
|
|
131
|
+
5. **Create CLI Tools**: Bundle creation and management
|
|
132
|
+
|
|
133
|
+
## 📝 Notes
|
|
134
|
+
|
|
135
|
+
- Each item should be completed with tests
|
|
136
|
+
- Documentation should be updated as features are added
|
|
137
|
+
- Security should be considered in every component
|
|
138
|
+
- Performance impact should be measured
|
|
139
|
+
- Backward compatibility must be maintained
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# App Review API Reference
|
|
2
|
+
|
|
3
|
+
Complete API documentation for in-app review functionality.
|
|
4
|
+
|
|
5
|
+
## Methods
|
|
6
|
+
|
|
7
|
+
### requestReview(options?)
|
|
8
|
+
|
|
9
|
+
Request an in-app review dialog.
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
const result = await CapacitorNativeUpdate.requestReview({
|
|
13
|
+
force?: boolean; // Bypass rate limiting (testing only)
|
|
14
|
+
});
|
|
15
|
+
// Returns:
|
|
16
|
+
{
|
|
17
|
+
displayed: boolean; // Was review dialog shown?
|
|
18
|
+
reason?: string; // Why not displayed
|
|
19
|
+
platform: string; // Platform used
|
|
20
|
+
lastRequestDate?: number; // Last request timestamp
|
|
21
|
+
requestCount?: number; // Total request count
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### canRequestReview()
|
|
26
|
+
|
|
27
|
+
Check if a review can be requested (respects rate limits).
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
const result = await CapacitorNativeUpdate.canRequestReview();
|
|
31
|
+
// Returns:
|
|
32
|
+
{
|
|
33
|
+
canRequest: boolean;
|
|
34
|
+
reason?: string; // Why not available
|
|
35
|
+
lastRequestDate?: number; // Last request timestamp
|
|
36
|
+
requestCount?: number; // Times requested
|
|
37
|
+
daysUntilNext?: number; // Days until can request
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### openStoreReview()
|
|
42
|
+
|
|
43
|
+
Open the app store review page directly.
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
await CapacitorNativeUpdate.openStoreReview();
|
|
47
|
+
// Opens app store with review section focused
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### getStoreReviewUrl()
|
|
51
|
+
|
|
52
|
+
Get the store review URL without opening it.
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
const result = await CapacitorNativeUpdate.getStoreReviewUrl();
|
|
56
|
+
// Returns:
|
|
57
|
+
{
|
|
58
|
+
url: string; // Direct review URL
|
|
59
|
+
platform: 'ios' | 'android' | 'web';
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### resetReviewPrompts()
|
|
64
|
+
|
|
65
|
+
Reset review request history (testing only).
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
await CapacitorNativeUpdate.resetReviewPrompts();
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### setReviewConditions(conditions)
|
|
72
|
+
|
|
73
|
+
Set conditions for when to show review prompts.
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
await CapacitorNativeUpdate.setReviewConditions({
|
|
77
|
+
minimumDaysSinceInstall?: number; // Default: 3
|
|
78
|
+
minimumDaysSinceLastPrompt?: number; // Default: 90
|
|
79
|
+
minimumAppLaunches?: number; // Default: 5
|
|
80
|
+
minimumSignificantEvents?: number; // Default: 3
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### trackSignificantEvent(eventName)
|
|
85
|
+
|
|
86
|
+
Track significant events for review timing.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
await CapacitorNativeUpdate.trackSignificantEvent(eventName: string);
|
|
90
|
+
// Examples: 'purchase_completed', 'level_completed', 'content_shared'
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Events
|
|
94
|
+
|
|
95
|
+
### reviewPromptDisplayed
|
|
96
|
+
|
|
97
|
+
Fired when review prompt is shown.
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
CapacitorNativeUpdate.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
|
+
CapacitorNativeUpdate.addListener('reviewPromptDismissed', (event) => {
|
|
112
|
+
console.log('Review prompt dismissed');
|
|
113
|
+
analytics.track('review_prompt_dismissed');
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Platform Implementation
|
|
118
|
+
|
|
119
|
+
### iOS (StoreKit)
|
|
120
|
+
|
|
121
|
+
- Uses `SKStoreReviewController.requestReview()`
|
|
122
|
+
- Limited to 3 prompts per 365-day period
|
|
123
|
+
- No callback for user action
|
|
124
|
+
- Shows native iOS review dialog
|
|
125
|
+
- Requires iOS 10.3+
|
|
126
|
+
|
|
127
|
+
### Android (Google Play)
|
|
128
|
+
|
|
129
|
+
- Uses Play Core In-App Review API
|
|
130
|
+
- No specific rate limits documented
|
|
131
|
+
- Shows native Play Store review flow
|
|
132
|
+
- Requires Play Core Library
|
|
133
|
+
- Android 5.0+ (API 21+)
|
|
134
|
+
|
|
135
|
+
### Web
|
|
136
|
+
|
|
137
|
+
- Shows custom review prompt
|
|
138
|
+
- Redirects to review URL
|
|
139
|
+
- No rate limiting
|
|
140
|
+
- Customizable UI
|
|
141
|
+
|
|
142
|
+
## Best Practices
|
|
143
|
+
|
|
144
|
+
### 1. Time Review Requests Appropriately
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
// After positive interaction
|
|
148
|
+
async function onPurchaseComplete() {
|
|
149
|
+
await processPayment();
|
|
150
|
+
await showThankYouMessage();
|
|
151
|
+
|
|
152
|
+
// Wait a bit, then request review
|
|
153
|
+
setTimeout(async () => {
|
|
154
|
+
const { canRequest } = await CapacitorNativeUpdate.canRequestReview();
|
|
155
|
+
if (canRequest) {
|
|
156
|
+
await CapacitorNativeUpdate.requestReview();
|
|
157
|
+
}
|
|
158
|
+
}, 2000);
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 2. Track Significant Events
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// Define what counts as significant
|
|
166
|
+
const SIGNIFICANT_EVENTS = [
|
|
167
|
+
'tutorial_completed',
|
|
168
|
+
'first_purchase',
|
|
169
|
+
'level_10_reached',
|
|
170
|
+
'friend_invited',
|
|
171
|
+
'content_created'
|
|
172
|
+
];
|
|
173
|
+
|
|
174
|
+
async function trackUserAction(action: string) {
|
|
175
|
+
if (SIGNIFICANT_EVENTS.includes(action)) {
|
|
176
|
+
await CapacitorNativeUpdate.trackSignificantEvent(action);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### 3. Implement Smart Conditions
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
// Configure smart conditions
|
|
185
|
+
await CapacitorNativeUpdate.setReviewConditions({
|
|
186
|
+
minimumDaysSinceInstall: 7, // Week after install
|
|
187
|
+
minimumDaysSinceLastPrompt: 120, // 4 months between
|
|
188
|
+
minimumAppLaunches: 10, // Regular user
|
|
189
|
+
minimumSignificantEvents: 5 // Engaged user
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### 4. Fallback Strategy
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
async function requestReviewSmart() {
|
|
197
|
+
try {
|
|
198
|
+
const { displayed } = await CapacitorNativeUpdate.requestReview();
|
|
199
|
+
|
|
200
|
+
if (!displayed) {
|
|
201
|
+
// Fallback: Show custom UI with store link
|
|
202
|
+
const response = await showCustomReviewDialog();
|
|
203
|
+
if (response === 'yes') {
|
|
204
|
+
await CapacitorNativeUpdate.openStoreReview();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
} catch (error) {
|
|
208
|
+
console.error('Review request failed:', error);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Rate Limiting
|
|
214
|
+
|
|
215
|
+
### iOS Limits
|
|
216
|
+
- Maximum 3 prompts per 365 days
|
|
217
|
+
- No prompt if user has already rated
|
|
218
|
+
- System decides when to show
|
|
219
|
+
|
|
220
|
+
### Android Guidelines
|
|
221
|
+
- No hard limits specified
|
|
222
|
+
- Don't prompt during onboarding
|
|
223
|
+
- Don't prompt after errors
|
|
224
|
+
- Respect user choice
|
|
225
|
+
|
|
226
|
+
### Custom Implementation
|
|
227
|
+
```typescript
|
|
228
|
+
class ReviewManager {
|
|
229
|
+
private readonly MAX_REQUESTS_PER_YEAR = 3;
|
|
230
|
+
private readonly DAYS_BETWEEN_PROMPTS = 120;
|
|
231
|
+
|
|
232
|
+
async canRequestReview(): Promise<boolean> {
|
|
233
|
+
const history = await this.getRequestHistory();
|
|
234
|
+
const now = Date.now();
|
|
235
|
+
const oneYearAgo = now - (365 * 24 * 60 * 60 * 1000);
|
|
236
|
+
|
|
237
|
+
const recentRequests = history.filter(date => date > oneYearAgo);
|
|
238
|
+
|
|
239
|
+
if (recentRequests.length >= this.MAX_REQUESTS_PER_YEAR) {
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const lastRequest = Math.max(...history);
|
|
244
|
+
const daysSinceLastRequest = (now - lastRequest) / (24 * 60 * 60 * 1000);
|
|
245
|
+
|
|
246
|
+
return daysSinceLastRequest >= this.DAYS_BETWEEN_PROMPTS;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Error Codes
|
|
252
|
+
|
|
253
|
+
| Code | Description |
|
|
254
|
+
|------|-------------|
|
|
255
|
+
| `RATE_LIMITED` | Too many recent requests |
|
|
256
|
+
| `CONDITIONS_NOT_MET` | Review conditions not satisfied |
|
|
257
|
+
| `PLATFORM_NOT_SUPPORTED` | Feature not available on platform |
|
|
258
|
+
| `USER_CANCELLED` | User dismissed the prompt |
|
|
259
|
+
| `ALREADY_RATED` | User has already rated the app |
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# App Update API Reference
|
|
2
|
+
|
|
3
|
+
Complete API documentation for native app store update functionality.
|
|
4
|
+
|
|
5
|
+
## Methods
|
|
6
|
+
|
|
7
|
+
### checkAppUpdate()
|
|
8
|
+
|
|
9
|
+
Check if a native app update is available in the app store.
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
const result = await CapacitorNativeUpdate.checkAppUpdate();
|
|
13
|
+
// Returns:
|
|
14
|
+
{
|
|
15
|
+
updateAvailable: boolean;
|
|
16
|
+
currentVersion: string;
|
|
17
|
+
availableVersion?: string;
|
|
18
|
+
updatePriority?: 'LOW' | 'MEDIUM' | 'HIGH' | 'IMMEDIATE';
|
|
19
|
+
releaseNotes?: string;
|
|
20
|
+
updateSize?: number;
|
|
21
|
+
|
|
22
|
+
// Android specific
|
|
23
|
+
immediateUpdateAllowed?: boolean;
|
|
24
|
+
flexibleUpdateAllowed?: boolean;
|
|
25
|
+
clientVersionStalenessDays?: number;
|
|
26
|
+
|
|
27
|
+
// iOS specific
|
|
28
|
+
updateURL?: string;
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### startImmediateUpdate()
|
|
33
|
+
|
|
34
|
+
Start an immediate (blocking) update. Android only - shows full-screen update UI.
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
try {
|
|
38
|
+
await CapacitorNativeUpdate.startImmediateUpdate();
|
|
39
|
+
// App will restart after update
|
|
40
|
+
} catch (error) {
|
|
41
|
+
// User cancelled or update failed
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### startFlexibleUpdate()
|
|
46
|
+
|
|
47
|
+
Start a flexible (background) update. Android only - downloads in background.
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
await CapacitorNativeUpdate.startFlexibleUpdate();
|
|
51
|
+
// Monitor progress with appUpdateProgress event
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### completeFlexibleUpdate()
|
|
55
|
+
|
|
56
|
+
Complete a flexible update installation. Android only.
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
await CapacitorNativeUpdate.completeFlexibleUpdate();
|
|
60
|
+
// App will restart
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### getVersionInfo()
|
|
64
|
+
|
|
65
|
+
Get detailed version information.
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
const info = await CapacitorNativeUpdate.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 CapacitorNativeUpdate.isMinimumVersionMet();
|
|
86
|
+
// Returns:
|
|
87
|
+
{
|
|
88
|
+
isMet: boolean;
|
|
89
|
+
currentVersion: string;
|
|
90
|
+
minimumVersion: string;
|
|
91
|
+
updateRequired: boolean;
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### openAppStore()
|
|
96
|
+
|
|
97
|
+
Open the app store page for updates.
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
await CapacitorNativeUpdate.openAppStore();
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### getAppStoreUrl()
|
|
104
|
+
|
|
105
|
+
Get the app store URL without opening it.
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
const result = await CapacitorNativeUpdate.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 CapacitorNativeUpdate.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
|
+
CapacitorNativeUpdate.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
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### appUpdateProgress
|
|
153
|
+
|
|
154
|
+
Fired during flexible update download. Android only.
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
CapacitorNativeUpdate.addListener('appUpdateProgress', (progress) => {
|
|
158
|
+
console.log(`Downloaded: ${progress.bytesDownloaded}/${progress.totalBytesToDownload}`);
|
|
159
|
+
console.log(`Progress: ${progress.percentComplete}%`);
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Platform Differences
|
|
164
|
+
|
|
165
|
+
### Android (Google Play)
|
|
166
|
+
|
|
167
|
+
- Supports in-app updates via Play Core Library
|
|
168
|
+
- Two update modes: Immediate and Flexible
|
|
169
|
+
- Can force critical updates
|
|
170
|
+
- Shows native update UI
|
|
171
|
+
- Handles download and installation
|
|
172
|
+
|
|
173
|
+
### iOS (App Store)
|
|
174
|
+
|
|
175
|
+
- No in-app update API available
|
|
176
|
+
- Can only check version and open App Store
|
|
177
|
+
- Version checking requires backend service
|
|
178
|
+
- Updates handled entirely by App Store app
|
|
179
|
+
|
|
180
|
+
### Web
|
|
181
|
+
|
|
182
|
+
- Shows update notification only
|
|
183
|
+
- Can redirect to web app URL
|
|
184
|
+
- Version checking via backend
|
|
185
|
+
|
|
186
|
+
## Error Codes
|
|
187
|
+
|
|
188
|
+
| Code | Description |
|
|
189
|
+
|------|-------------|
|
|
190
|
+
| `UPDATE_NOT_AVAILABLE` | No update available |
|
|
191
|
+
| `UPDATE_IN_PROGRESS` | Update already downloading |
|
|
192
|
+
| `UPDATE_FAILED` | Update download/install failed |
|
|
193
|
+
| `USER_CANCELLED` | User cancelled the update |
|
|
194
|
+
| `PLATFORM_NOT_SUPPORTED` | Feature not supported on platform |
|
|
195
|
+
| `STORE_NOT_FOUND` | App store app not installed |
|
|
196
|
+
| `NETWORK_ERROR` | Network connection failed |
|
|
197
|
+
|
|
198
|
+
## Best Practices
|
|
199
|
+
|
|
200
|
+
1. **Check for updates on app start**
|
|
201
|
+
```typescript
|
|
202
|
+
async function checkOnStart() {
|
|
203
|
+
const result = await CapacitorNativeUpdate.checkAppUpdate();
|
|
204
|
+
if (result.updateAvailable && result.updatePriority === 'IMMEDIATE') {
|
|
205
|
+
await CapacitorNativeUpdate.startImmediateUpdate();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
2. **Handle flexible updates**
|
|
211
|
+
```typescript
|
|
212
|
+
// Start download
|
|
213
|
+
await CapacitorNativeUpdate.startFlexibleUpdate();
|
|
214
|
+
|
|
215
|
+
// Monitor progress
|
|
216
|
+
const listener = CapacitorNativeUpdate.addListener('appUpdateProgress', (progress) => {
|
|
217
|
+
updateProgressBar(progress.percentComplete);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Complete when ready
|
|
221
|
+
const stateListener = CapacitorNativeUpdate.addListener('appUpdateStateChanged', (state) => {
|
|
222
|
+
if (state.installStatus === 11) { // Downloaded
|
|
223
|
+
showUpdateReadyPrompt();
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
3. **Fallback for iOS**
|
|
229
|
+
```typescript
|
|
230
|
+
if (platform === 'ios') {
|
|
231
|
+
const result = await CapacitorNativeUpdate.checkAppUpdate();
|
|
232
|
+
if (result.updateAvailable) {
|
|
233
|
+
showUpdateDialog(() => {
|
|
234
|
+
CapacitorNativeUpdate.openAppStore();
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
```
|