cordova-plugin-hot-updates 2.1.1 → 2.1.2
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/README.md +336 -186
- package/package.json +4 -5
- package/plugin.xml +5 -10
- package/src/ios/HotUpdates.m +2 -2
- package/www/HotUpdates.js +162 -142
- package/CHANGELOG.md +0 -239
- package/docs/API.md +0 -352
- package/docs/README.md +0 -187
- package/docs/hot-updates-admin.html +0 -467
package/README.md
CHANGED
|
@@ -1,31 +1,23 @@
|
|
|
1
|
-
# Cordova Hot Updates Plugin
|
|
1
|
+
# Cordova Hot Updates Plugin v2.1.2
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Frontend-controlled manual hot updates for Cordova iOS applications using WebView Reload approach.
|
|
4
4
|
|
|
5
5
|
[](https://badge.fury.io/js/cordova-plugin-hot-updates)
|
|
6
6
|
[](#license)
|
|
7
7
|
|
|
8
8
|
This plugin enables **manual, JavaScript-controlled** web content updates for your Cordova iOS applications without requiring App Store approval. Your frontend code decides when to check, download, and install updates.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Features
|
|
11
11
|
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
12
|
+
- **Frontend Control**: JavaScript decides when to update (no automatic background checking)
|
|
13
|
+
- **Two-Step Updates**: Separate download (`getUpdate`) and install (`forceUpdate`) for better UX
|
|
14
|
+
- **Auto-Install on Launch**: If user ignores update prompt, it installs on next app launch
|
|
15
|
+
- **Canary System**: Automatic rollback if update fails to load (20-second timeout)
|
|
16
|
+
- **IgnoreList**: Tracks problematic versions (information only, does NOT block installation)
|
|
17
|
+
- **Instant Effect**: WebView Reload approach - no app restart needed
|
|
18
|
+
- **Cache Management**: Clears WKWebView cache (disk, memory, Service Worker) before reload
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
## 🎯 Key Features
|
|
20
|
-
|
|
21
|
-
- **🎮 Frontend Control**: Your JavaScript decides when to update (no automatic background checks)
|
|
22
|
-
- **⚡ Two-Step Updates**: Separate download and install for better UX
|
|
23
|
-
- **🔄 Auto-Install**: If user ignores popup, update installs on next app launch
|
|
24
|
-
- **🐦 Canary System**: Automatic rollback if update fails to load (20-second timeout)
|
|
25
|
-
- **📋 IgnoreList**: Tracks problematic versions (informational only)
|
|
26
|
-
- **🚀 Instant Effect**: WebView Reload approach - no app restart needed
|
|
27
|
-
|
|
28
|
-
## 📦 Installation
|
|
20
|
+
## Installation
|
|
29
21
|
|
|
30
22
|
```bash
|
|
31
23
|
# Install from npm
|
|
@@ -36,166 +28,298 @@ cd platforms/ios
|
|
|
36
28
|
pod install
|
|
37
29
|
```
|
|
38
30
|
|
|
31
|
+
Or install from local directory:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
cordova plugin add /path/to/cordova-plugin-hot-updates
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Or install from GitHub:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
cordova plugin add https://github.com/vladimirDarksy/Cordova_hot_update.git
|
|
41
|
+
```
|
|
42
|
+
|
|
39
43
|
**Requirements:**
|
|
40
44
|
- Cordova >= 7.0.0
|
|
41
45
|
- cordova-ios >= 4.4.0
|
|
42
|
-
- iOS >= 11.
|
|
46
|
+
- iOS >= 11.2
|
|
43
47
|
- CocoaPods (for SSZipArchive dependency)
|
|
44
48
|
|
|
45
|
-
##
|
|
49
|
+
## Quick Start
|
|
46
50
|
|
|
47
51
|
### 1. Minimal Integration
|
|
48
52
|
|
|
49
53
|
```javascript
|
|
50
54
|
document.addEventListener('deviceready', function() {
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
url: data.downloadURL,
|
|
69
|
-
version: data.newVersion
|
|
70
|
-
}, function(error) {
|
|
71
|
-
if (error) {
|
|
72
|
-
console.error('Download failed:', error.error.message);
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
55
|
+
// CRITICAL: Confirm successful bundle load within 20 seconds
|
|
56
|
+
var currentVersion = localStorage.getItem('app_version') || '1.0.0';
|
|
57
|
+
window.hotUpdate.canary(currentVersion);
|
|
58
|
+
|
|
59
|
+
// Check for updates
|
|
60
|
+
checkForUpdates();
|
|
61
|
+
}, false);
|
|
62
|
+
|
|
63
|
+
function checkForUpdates() {
|
|
64
|
+
fetch('https://your-server.com/api/check-update?version=1.0.0')
|
|
65
|
+
.then(response => response.json())
|
|
66
|
+
.then(data => {
|
|
67
|
+
if (data.hasUpdate) {
|
|
68
|
+
downloadAndInstall(data.downloadUrl, data.version);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
75
72
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
// WebView reloads automatically
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
// If user cancels: update installs automatically on next launch
|
|
87
|
-
});
|
|
88
|
-
}
|
|
73
|
+
function downloadAndInstall(url, version) {
|
|
74
|
+
window.hotUpdate.getUpdate({url: url, version: version}, function(error) {
|
|
75
|
+
if (!error) {
|
|
76
|
+
if (confirm('Update available. Install now?')) {
|
|
77
|
+
localStorage.setItem('app_version', version);
|
|
78
|
+
window.hotUpdate.forceUpdate(function(error) {
|
|
79
|
+
// WebView will reload, canary() will be called in deviceready
|
|
89
80
|
});
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
'getVersionInfo',
|
|
96
|
-
[]
|
|
97
|
-
);
|
|
98
|
-
});
|
|
81
|
+
}
|
|
82
|
+
// If user declines, update auto-installs on next launch
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
99
86
|
```
|
|
100
87
|
|
|
101
|
-
##
|
|
88
|
+
## API Reference
|
|
89
|
+
|
|
90
|
+
All API methods are available via `window.hotUpdate` after the `deviceready` event.
|
|
102
91
|
|
|
103
|
-
###
|
|
92
|
+
### window.hotUpdate.getUpdate(options, callback)
|
|
104
93
|
|
|
105
|
-
|
|
94
|
+
Downloads update from server.
|
|
106
95
|
|
|
107
|
-
Downloads
|
|
96
|
+
Downloads ZIP from provided URL and saves to two locations:
|
|
97
|
+
- `temp_downloaded_update` (for immediate installation via `forceUpdate()`)
|
|
98
|
+
- `pending_update` (for auto-installation on next app launch)
|
|
108
99
|
|
|
100
|
+
If version already downloaded, returns success without re-downloading.
|
|
101
|
+
|
|
102
|
+
**Does NOT check ignoreList** - JavaScript controls all installation decisions.
|
|
103
|
+
|
|
104
|
+
**Parameters:**
|
|
105
|
+
- `options` (Object):
|
|
106
|
+
- `url` (string, required) - URL to download ZIP archive
|
|
107
|
+
- `version` (string, optional) - Version string
|
|
108
|
+
- `callback` (Function) - `callback(error)`
|
|
109
|
+
- `null` on success
|
|
110
|
+
- `{error: {message?: string}}` on error
|
|
111
|
+
|
|
112
|
+
**Example:**
|
|
109
113
|
```javascript
|
|
110
|
-
window.
|
|
111
|
-
url: 'https://server.com/updates/2.
|
|
112
|
-
version: '2.
|
|
114
|
+
window.hotUpdate.getUpdate({
|
|
115
|
+
url: 'https://your-server.com/updates/2.0.0.zip',
|
|
116
|
+
version: '2.0.0'
|
|
113
117
|
}, function(error) {
|
|
114
118
|
if (error) {
|
|
115
|
-
console.error('Download failed:', error
|
|
119
|
+
console.error('Download failed:', error);
|
|
116
120
|
} else {
|
|
117
|
-
console.log('
|
|
121
|
+
console.log('Update downloaded successfully');
|
|
118
122
|
}
|
|
119
123
|
});
|
|
120
124
|
```
|
|
121
125
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
### window.hotUpdate.forceUpdate(callback)
|
|
129
|
+
|
|
130
|
+
Installs downloaded update immediately and reloads WebView.
|
|
126
131
|
|
|
127
|
-
|
|
132
|
+
**Process:**
|
|
133
|
+
1. Backup current version to `www_previous`
|
|
134
|
+
2. Copy downloaded update to `Documents/www`
|
|
135
|
+
3. Clear WebView cache (disk, memory, Service Worker)
|
|
136
|
+
4. Reload WebView
|
|
137
|
+
5. Start 20-second canary timer
|
|
128
138
|
|
|
129
|
-
|
|
139
|
+
**IMPORTANT:** JavaScript MUST call `canary(version)` within 20 seconds after reload to confirm successful bundle load. Otherwise automatic rollback occurs.
|
|
130
140
|
|
|
141
|
+
**Does NOT check ignoreList** - JavaScript decides what to install.
|
|
142
|
+
|
|
143
|
+
**Parameters:**
|
|
144
|
+
- `callback` (Function) - `callback(error)`
|
|
145
|
+
- `null` on success (before WebView reload)
|
|
146
|
+
- `{error: {message?: string}}` on error
|
|
147
|
+
|
|
148
|
+
**Example:**
|
|
131
149
|
```javascript
|
|
132
|
-
window.
|
|
150
|
+
window.hotUpdate.forceUpdate(function(error) {
|
|
133
151
|
if (error) {
|
|
134
|
-
console.error('Install failed:', error
|
|
152
|
+
console.error('Install failed:', error);
|
|
135
153
|
} else {
|
|
136
|
-
console.log('
|
|
154
|
+
console.log('Update installing, WebView will reload...');
|
|
137
155
|
}
|
|
138
156
|
});
|
|
139
157
|
```
|
|
140
158
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
### window.hotUpdate.canary(version, callback)
|
|
162
|
+
|
|
163
|
+
Confirms successful bundle load after update.
|
|
164
|
+
|
|
165
|
+
**MUST be called within 20 seconds** after `forceUpdate()` to stop canary timer and prevent automatic rollback.
|
|
145
166
|
|
|
146
|
-
|
|
167
|
+
**If not called within 20 seconds:**
|
|
168
|
+
- Automatic rollback to previous version
|
|
169
|
+
- Failed version added to ignoreList
|
|
170
|
+
- WebView reloaded with previous version
|
|
147
171
|
|
|
148
|
-
|
|
172
|
+
**Parameters:**
|
|
173
|
+
- `version` (string) - Version that loaded successfully
|
|
174
|
+
- `callback` (Function, optional) - Not used, method is synchronous
|
|
149
175
|
|
|
176
|
+
**Example:**
|
|
150
177
|
```javascript
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
178
|
+
document.addEventListener('deviceready', function() {
|
|
179
|
+
var version = localStorage.getItem('app_version') || '1.0.0';
|
|
180
|
+
window.hotUpdate.canary(version);
|
|
181
|
+
}, false);
|
|
154
182
|
```
|
|
155
183
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
### window.hotUpdate.getIgnoreList(callback)
|
|
187
|
+
|
|
188
|
+
Returns list of problematic versions (information only).
|
|
189
|
+
|
|
190
|
+
**This is an INFORMATION-ONLY system** - native does NOT block installation. JavaScript should read this list and decide whether to skip these versions.
|
|
160
191
|
|
|
161
|
-
|
|
192
|
+
Native automatically adds versions to this list when rollback occurs.
|
|
162
193
|
|
|
163
|
-
|
|
194
|
+
**Parameters:**
|
|
195
|
+
- `callback` (Function) - `callback(result)`
|
|
196
|
+
- `result`: `{versions: string[]}` - Array of problematic version strings
|
|
164
197
|
|
|
198
|
+
**Example:**
|
|
165
199
|
```javascript
|
|
166
|
-
window.
|
|
167
|
-
|
|
200
|
+
window.hotUpdate.getIgnoreList(function(result) {
|
|
201
|
+
console.log('Problematic versions:', result.versions);
|
|
168
202
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
// Safe to download
|
|
203
|
+
if (result.versions.includes(newVersion)) {
|
|
204
|
+
console.log('Skipping known problematic version');
|
|
172
205
|
}
|
|
173
206
|
});
|
|
174
207
|
```
|
|
175
208
|
|
|
176
|
-
|
|
209
|
+
---
|
|
177
210
|
|
|
178
|
-
##
|
|
211
|
+
## Complete Update Flow
|
|
179
212
|
|
|
180
|
-
|
|
213
|
+
```javascript
|
|
214
|
+
// Step 1: Check for updates on your server
|
|
215
|
+
function checkForUpdates() {
|
|
216
|
+
var currentVersion = localStorage.getItem('app_version') || '1.0.0';
|
|
217
|
+
|
|
218
|
+
fetch('https://your-server.com/api/check-update?version=' + currentVersion)
|
|
219
|
+
.then(response => response.json())
|
|
220
|
+
.then(data => {
|
|
221
|
+
if (data.hasUpdate) {
|
|
222
|
+
// Step 2: Check ignoreList
|
|
223
|
+
window.hotUpdate.getIgnoreList(function(ignoreList) {
|
|
224
|
+
if (ignoreList.versions.includes(data.version)) {
|
|
225
|
+
console.log('Skipping problematic version');
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Step 3: Download
|
|
230
|
+
window.hotUpdate.getUpdate({
|
|
231
|
+
url: data.downloadUrl,
|
|
232
|
+
version: data.version
|
|
233
|
+
}, function(error) {
|
|
234
|
+
if (!error) {
|
|
235
|
+
// Step 4: Prompt user
|
|
236
|
+
if (confirm('Update available. Install now?')) {
|
|
237
|
+
// Save version for canary check
|
|
238
|
+
localStorage.setItem('app_version', data.version);
|
|
239
|
+
|
|
240
|
+
// Step 5: Install
|
|
241
|
+
window.hotUpdate.forceUpdate(function(error) {
|
|
242
|
+
// WebView will reload
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
// If declined, auto-installs on next launch
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
}
|
|
181
252
|
|
|
182
|
-
|
|
253
|
+
// Step 6: After reload, confirm success
|
|
254
|
+
document.addEventListener('deviceready', function() {
|
|
255
|
+
var version = localStorage.getItem('app_version') || '1.0.0';
|
|
256
|
+
window.hotUpdate.canary(version); // Must call within 20 seconds!
|
|
257
|
+
|
|
258
|
+
initApp();
|
|
259
|
+
}, false);
|
|
260
|
+
```
|
|
183
261
|
|
|
184
|
-
|
|
262
|
+
## How It Works
|
|
185
263
|
|
|
186
|
-
|
|
264
|
+
### Update Flow
|
|
265
|
+
|
|
266
|
+
1. **Download** (`getUpdate()`):
|
|
267
|
+
- Downloads ZIP from URL
|
|
268
|
+
- Validates `www` folder structure
|
|
269
|
+
- Saves to TWO locations:
|
|
270
|
+
- `temp_downloaded_update` (for immediate install)
|
|
271
|
+
- `pending_update` (for auto-install on next launch)
|
|
272
|
+
|
|
273
|
+
2. **Installation Options**:
|
|
274
|
+
- **Immediate**: User clicks "Update" → `forceUpdate()` installs now
|
|
275
|
+
- **Deferred**: User ignores → Auto-installs on next app launch
|
|
276
|
+
|
|
277
|
+
3. **Rollback Protection**:
|
|
278
|
+
- Previous version backed up before installation
|
|
279
|
+
- 20-second canary timer starts after reload
|
|
280
|
+
- If `canary()` not called → automatic rollback
|
|
281
|
+
- Failed version added to ignoreList
|
|
282
|
+
|
|
283
|
+
4. **IgnoreList System**:
|
|
284
|
+
- Native tracks failed versions
|
|
285
|
+
- JavaScript reads via `getIgnoreList()`
|
|
286
|
+
- **Does NOT block** - JS decides what to install
|
|
287
|
+
|
|
288
|
+
### Storage Structure
|
|
289
|
+
|
|
290
|
+
```
|
|
291
|
+
Documents/
|
|
292
|
+
├── www/ // Active version
|
|
293
|
+
├── www_previous/ // Previous version (rollback)
|
|
294
|
+
├── pending_update/ // Next launch auto-install
|
|
295
|
+
└── temp_downloaded_update/ // Immediate install
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Version Management
|
|
299
|
+
|
|
300
|
+
- **appBundleVersion** - Native app version from Info.plist
|
|
301
|
+
- **installedVersion** - Current hot update version
|
|
302
|
+
- **previousVersion** - Last working version (rollback)
|
|
303
|
+
|
|
304
|
+
## Update Server API
|
|
305
|
+
|
|
306
|
+
Your server should provide:
|
|
307
|
+
|
|
308
|
+
**Check API:**
|
|
309
|
+
```
|
|
310
|
+
GET https://your-server.com/api/check-update?version=1.0.0&platform=ios
|
|
311
|
+
|
|
312
|
+
Response:
|
|
187
313
|
{
|
|
188
314
|
"hasUpdate": true,
|
|
189
|
-
"
|
|
190
|
-
"
|
|
191
|
-
"minAppVersion": "2.7.0"
|
|
315
|
+
"version": "2.0.0",
|
|
316
|
+
"downloadUrl": "https://your-server.com/updates/2.0.0.zip",
|
|
317
|
+
"minAppVersion": "2.7.0",
|
|
318
|
+
"releaseNotes": "Bug fixes"
|
|
192
319
|
}
|
|
193
320
|
```
|
|
194
321
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
ZIP file containing `www` folder:
|
|
198
|
-
|
|
322
|
+
**Update ZIP Structure:**
|
|
199
323
|
```
|
|
200
324
|
update.zip
|
|
201
325
|
└── www/
|
|
@@ -205,105 +329,131 @@ update.zip
|
|
|
205
329
|
└── ...
|
|
206
330
|
```
|
|
207
331
|
|
|
208
|
-
##
|
|
332
|
+
## Best Practices
|
|
209
333
|
|
|
210
|
-
###
|
|
334
|
+
### 1. Always Call Canary
|
|
211
335
|
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
5. User ignores: update auto-installs on next app launch
|
|
218
|
-
6. WebView reloads with new content
|
|
219
|
-
7. JS calls canary() to confirm success
|
|
336
|
+
```javascript
|
|
337
|
+
document.addEventListener('deviceready', function() {
|
|
338
|
+
var version = localStorage.getItem('app_version');
|
|
339
|
+
window.hotUpdate.canary(version); // Within 20 seconds!
|
|
340
|
+
}, false);
|
|
220
341
|
```
|
|
221
342
|
|
|
222
|
-
###
|
|
343
|
+
### 2. Check IgnoreList
|
|
223
344
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
345
|
+
```javascript
|
|
346
|
+
window.hotUpdate.getIgnoreList(function(result) {
|
|
347
|
+
if (result.versions.includes(newVersion)) {
|
|
348
|
+
console.log('Known problematic version');
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
```
|
|
228
352
|
|
|
229
|
-
###
|
|
353
|
+
### 3. Handle Errors
|
|
230
354
|
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
355
|
+
```javascript
|
|
356
|
+
window.hotUpdate.getUpdate(options, function(error) {
|
|
357
|
+
if (error) {
|
|
358
|
+
analytics.track('update_failed', {error: error.message});
|
|
359
|
+
showUserMessage('Update failed');
|
|
360
|
+
}
|
|
361
|
+
});
|
|
237
362
|
```
|
|
238
363
|
|
|
239
|
-
|
|
364
|
+
### 4. Store Version
|
|
240
365
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
- **[CHANGELOG.md](CHANGELOG.md)** - Version history
|
|
366
|
+
```javascript
|
|
367
|
+
// Before forceUpdate
|
|
368
|
+
localStorage.setItem('app_version', newVersion);
|
|
245
369
|
|
|
246
|
-
|
|
370
|
+
// After reload
|
|
371
|
+
var version = localStorage.getItem('app_version');
|
|
372
|
+
window.hotUpdate.canary(version);
|
|
373
|
+
```
|
|
247
374
|
|
|
248
|
-
|
|
375
|
+
## Troubleshooting
|
|
249
376
|
|
|
250
|
-
|
|
251
|
-
- Check `canary()` is called on every app start
|
|
252
|
-
- Verify server URL returns correct JSON
|
|
253
|
-
- Check iOS device logs for errors
|
|
377
|
+
### Update doesn't install
|
|
254
378
|
|
|
255
|
-
|
|
256
|
-
-
|
|
379
|
+
- Check ZIP structure (must have `www/` folder)
|
|
380
|
+
- Check URL accessibility
|
|
381
|
+
- Check Xcode console: `[HotUpdates] ...`
|
|
257
382
|
|
|
258
|
-
|
|
259
|
-
- ✅ Fixed in v2.1.0! Cache is cleared before reload
|
|
383
|
+
### Automatic rollback
|
|
260
384
|
|
|
261
|
-
**
|
|
262
|
-
```bash
|
|
263
|
-
cd platforms/ios
|
|
264
|
-
pod install
|
|
265
|
-
cordova clean ios && cordova build ios
|
|
266
|
-
```
|
|
385
|
+
**Cause:** `canary()` not called within 20 seconds
|
|
267
386
|
|
|
268
|
-
|
|
387
|
+
**Solution:** Call immediately in `deviceready`:
|
|
388
|
+
```javascript
|
|
389
|
+
document.addEventListener('deviceready', function() {
|
|
390
|
+
window.hotUpdate.canary(version); // First thing!
|
|
391
|
+
}, false);
|
|
392
|
+
```
|
|
269
393
|
|
|
270
|
-
|
|
394
|
+
### window.hotUpdate is undefined
|
|
271
395
|
|
|
272
|
-
|
|
273
|
-
# iOS Simulator
|
|
274
|
-
cordova run ios --debug
|
|
396
|
+
**Cause:** Called before `deviceready`
|
|
275
397
|
|
|
276
|
-
|
|
277
|
-
|
|
398
|
+
**Solution:**
|
|
399
|
+
```javascript
|
|
400
|
+
document.addEventListener('deviceready', function() {
|
|
401
|
+
console.log(window.hotUpdate); // Now available
|
|
402
|
+
}, false);
|
|
278
403
|
```
|
|
279
404
|
|
|
280
|
-
##
|
|
405
|
+
## Migration from v1.0.0
|
|
281
406
|
|
|
282
|
-
|
|
283
|
-
-
|
|
284
|
-
-
|
|
285
|
-
-
|
|
286
|
-
-
|
|
407
|
+
**Removed methods:**
|
|
408
|
+
- `getCurrentVersion()` - Manage in JS
|
|
409
|
+
- `getPendingUpdateInfo()` - Not needed
|
|
410
|
+
- `checkForUpdates()` - Frontend controls
|
|
411
|
+
- `downloadUpdate()` - Use `getUpdate()`
|
|
412
|
+
- `installUpdate()` - Use `forceUpdate()`
|
|
287
413
|
|
|
288
|
-
|
|
414
|
+
**New API:**
|
|
415
|
+
- `window.hotUpdate.getUpdate({url, version?}, callback)`
|
|
416
|
+
- `window.hotUpdate.forceUpdate(callback)`
|
|
417
|
+
- `window.hotUpdate.canary(version, callback)`
|
|
418
|
+
- `window.hotUpdate.getIgnoreList(callback)`
|
|
289
419
|
|
|
290
|
-
|
|
420
|
+
**Changes:**
|
|
421
|
+
- API via `window.hotUpdate` (not `window.HotUpdates`)
|
|
422
|
+
- Callback signature: `callback(error)` pattern
|
|
423
|
+
- No automatic background checking
|
|
291
424
|
|
|
292
|
-
##
|
|
425
|
+
## Changelog
|
|
293
426
|
|
|
294
|
-
|
|
427
|
+
### v2.1.2 (2025-11-13)
|
|
295
428
|
|
|
296
|
-
|
|
429
|
+
**Breaking Changes:**
|
|
430
|
+
- Changed API from `window.HotUpdates` to `window.hotUpdate`
|
|
431
|
+
- Removed automatic update checking
|
|
432
|
+
- Simplified to 4 methods: `getUpdate`, `forceUpdate`, `canary`, `getIgnoreList`
|
|
297
433
|
|
|
298
|
-
|
|
434
|
+
**New Features:**
|
|
435
|
+
- Frontend-controlled manual updates
|
|
436
|
+
- Two-step update flow
|
|
437
|
+
- 20-second canary timer
|
|
438
|
+
- IgnoreList system
|
|
439
|
+
- Auto-install on next launch
|
|
440
|
+
- WebView cache clearing
|
|
299
441
|
|
|
300
|
-
|
|
442
|
+
### v1.0.0
|
|
301
443
|
|
|
302
|
-
-
|
|
303
|
-
- **npm**: [cordova-plugin-hot-updates](https://www.npmjs.com/package/cordova-plugin-hot-updates)
|
|
444
|
+
- Initial release
|
|
304
445
|
|
|
305
|
-
|
|
446
|
+
## License
|
|
447
|
+
|
|
448
|
+
Custom Non-Commercial License - See [LICENSE](LICENSE) file
|
|
449
|
+
|
|
450
|
+
## Author
|
|
451
|
+
|
|
452
|
+
**Mustafin Vladimir**
|
|
453
|
+
- GitHub: [@vladimirDarksy](https://github.com/vladimirDarksy)
|
|
454
|
+
- Email: outvova.gor@gmail.com
|
|
306
455
|
|
|
307
|
-
|
|
456
|
+
## Support
|
|
308
457
|
|
|
309
|
-
|
|
458
|
+
- Issues: https://github.com/vladimirDarksy/Cordova_hot_update/issues
|
|
459
|
+
- Repository: https://github.com/vladimirDarksy/Cordova_hot_update
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cordova-plugin-hot-updates",
|
|
3
|
-
"version": "2.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.1.2",
|
|
4
|
+
"description": "Frontend-controlled manual hot updates for Cordova iOS apps using WebView Reload approach. Manual updates only, JavaScript controls all decisions.",
|
|
5
5
|
"main": "www/HotUpdates.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"over-the-air",
|
|
24
24
|
"webview",
|
|
25
25
|
"reload",
|
|
26
|
+
"manual",
|
|
26
27
|
"ecosystem:cordova",
|
|
27
28
|
"cordova-ios",
|
|
28
29
|
"mobile",
|
|
@@ -58,10 +59,8 @@
|
|
|
58
59
|
"www/",
|
|
59
60
|
"src/",
|
|
60
61
|
"scripts/",
|
|
61
|
-
"docs/",
|
|
62
62
|
"plugin.xml",
|
|
63
63
|
"README.md",
|
|
64
|
-
"LICENSE"
|
|
65
|
-
"CHANGELOG.md"
|
|
64
|
+
"LICENSE"
|
|
66
65
|
]
|
|
67
66
|
}
|