@capawesome/capacitor-live-update 6.7.2 → 7.0.0-dev.1765885034

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.
Files changed (56) hide show
  1. package/CapawesomeCapacitorLiveUpdate.podspec +3 -3
  2. package/Package.swift +32 -0
  3. package/README.md +419 -83
  4. package/android/build.gradle +12 -12
  5. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/LiveUpdate.java +758 -273
  6. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/LiveUpdateConfig.java +29 -27
  7. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/LiveUpdateHttpClient.java +40 -7
  8. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/LiveUpdatePlugin.java +212 -68
  9. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/LiveUpdatePreferences.java +52 -3
  10. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/classes/api/GetLatestBundleResponse.java +27 -0
  11. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/classes/events/DownloadBundleProgressEvent.java +32 -0
  12. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/classes/{results/GetBundleResult.java → events/NextBundleSetEvent.java} +9 -7
  13. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/classes/options/DownloadBundleOptions.java +16 -1
  14. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/classes/options/SetConfigOptions.java +19 -0
  15. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/classes/options/SyncOptions.java +4 -0
  16. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/classes/results/FetchLatestBundleResult.java +29 -1
  17. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/classes/results/GetBlockedBundlesResult.java +27 -0
  18. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/classes/results/GetConfigResult.java +40 -0
  19. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/classes/results/GetDownloadedBundlesResult.java +27 -0
  20. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/classes/results/IsSyncingResult.java +26 -0
  21. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/classes/results/ReadyResult.java +32 -0
  22. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/interfaces/DownloadProgressCallback.java +5 -0
  23. package/dist/docs.json +630 -103
  24. package/dist/esm/definitions.d.ts +365 -39
  25. package/dist/esm/definitions.js.map +1 -1
  26. package/dist/esm/index.js +1 -1
  27. package/dist/esm/index.js.map +1 -1
  28. package/dist/esm/web.d.ts +9 -2
  29. package/dist/esm/web.js +21 -0
  30. package/dist/esm/web.js.map +1 -1
  31. package/dist/plugin.cjs.js +22 -3
  32. package/dist/plugin.cjs.js.map +1 -1
  33. package/dist/plugin.js +22 -3
  34. package/dist/plugin.js.map +1 -1
  35. package/ios/Plugin/Classes/Events/DownloadBundleProgressEvent.swift +25 -0
  36. package/ios/Plugin/Classes/{Results/GetBundleResult.swift → Events/NextBundleSetEvent.swift} +3 -3
  37. package/ios/Plugin/Classes/Options/DownloadBundleOptions.swift +7 -1
  38. package/ios/Plugin/Classes/Options/SetConfigOptions.swift +14 -0
  39. package/ios/Plugin/Classes/Options/SyncOptions.swift +4 -0
  40. package/ios/Plugin/Classes/Results/{FetchLatestBundle.swift → FetchLatestBundleResult.swift} +16 -1
  41. package/ios/Plugin/Classes/Results/GetBlockedBundlesResult.swift +16 -0
  42. package/ios/Plugin/Classes/Results/GetConfigResult.swift +19 -0
  43. package/ios/Plugin/Classes/Results/GetDownloadedBundlesResult.swift +16 -0
  44. package/ios/Plugin/Classes/Results/IsSyncingResult.swift +16 -0
  45. package/ios/Plugin/Classes/Results/ReadyResult.swift +22 -0
  46. package/ios/Plugin/LiveUpdate.swift +370 -151
  47. package/ios/Plugin/LiveUpdateConfig.swift +4 -4
  48. package/ios/Plugin/LiveUpdateHttpClient.swift +10 -4
  49. package/ios/Plugin/LiveUpdatePlugin.swift +138 -35
  50. package/ios/Plugin/LiveUpdatePreferences.swift +56 -14
  51. package/ios/Plugin/Protocols/Api/GetLatestBundleResponse.swift +3 -0
  52. package/package.json +19 -20
  53. package/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/classes/options/SetBundleOptions.java +0 -18
  54. package/ios/Plugin/Classes/Options/SetBundleOptions.swift +0 -14
  55. package/ios/Plugin/LiveUpdatePlugin.h +0 -10
  56. package/ios/Plugin/LiveUpdatePlugin.m +0 -27
package/README.md CHANGED
@@ -1,21 +1,51 @@
1
1
  # @capawesome/capacitor-live-update
2
2
 
3
- Capacitor plugin to update your app remotely in real-time.
3
+ Capacitor plugin that allows you to update your app remotely in real-time without requiring users to download a new version from the app store, known as Over-the-Air (OTA) updates.
4
+
5
+ <div class="capawesome-z29o10a">
6
+ <a href="https://cloud.capawesome.io/" target="_blank">
7
+ <img alt="Deliver Live Updates to your Capacitor app with Capawesome Cloud" src="https://cloud.capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png?t=1" />
8
+ </a>
9
+ </div>
4
10
 
5
11
  ## Features
6
12
 
13
+ We are proud to offer one of the most complete and feature-rich Capacitor plugins for Over-the-Air (OTA) updates. Here are some of the key features:
14
+
7
15
  - 🔋 Supports **Android and iOS**
8
- - ⚡️ **Capacitor 6** support
16
+ - ⚡️ **Capacitor 7** support
9
17
  - 📦 **Bundle Management**: Download, set, and delete bundles.
10
- - ☁️ **Cloud Support**: Use the [Capawesome Cloud](https://capawesome.io/cloud/live-updates/) to manage your app updates.
18
+ - ☁️ **Cloud Support**: Use the [Capawesome Cloud](https://cloud.capawesome.io/) to manage your app updates.
11
19
  - 📺 **Channel Support**: Set a channel for the app to manage different versions.
12
- - 🔄 **Auto Update**: Automatically download and set the latest bundle for the app.
20
+ - 🔄 **Auto Update**: Automatically download and set the latest bundle for the app with configurable background update strategy.
13
21
  - 🛟 **Rollback**: Reset the app to the default bundle if an incompatible bundle has been set.
14
22
  - 🚀 **Rollout**: Gradually roll out new bundles to gather valuable feedback.
15
23
  - 🔁 **Delta Updates**: Make your updates faster by only downloading changed files.
16
24
  - 🔒 **Security**: Verify the authenticity and integrity of the bundle using a public key.
25
+ - ⚔️ **Battle-Tested**: Used in more than 1,000 projects to update apps on more than 20,000,000 devices.
17
26
  - 🌐 **Open Source**: Licensed under the MIT License.
18
27
 
28
+ Missing a feature? Just [open an issue](https://github.com/capawesome-team/capacitor-plugins/issues) and we'll take a look!
29
+
30
+ ## Compatibility
31
+
32
+ | Plugin Version | Capacitor Version | Status |
33
+ | -------------- | ----------------- | -------------- |
34
+ | 8.x.x | >=8.x.x | Active support |
35
+ | 7.x.x | 7.x.x | Deprecated |
36
+ | 6.x.x | 6.x.x | Deprecated |
37
+ | 5.x.x | 5.x.x | Deprecated |
38
+
39
+ ## Guides
40
+
41
+ - [Announcing the Capacitor Live Update Plugin](https://capawesome.io/blog/announcing-the-capacitor-live-update-plugin/)
42
+ - [Exploring the Capacitor Live Update API](https://capawesome.io/blog/exploring-the-capacitor-live-update-api/)
43
+ - [How Live Updates for Capacitor work](https://capawesome.io/blog/how-live-updates-for-capacitor-work/)
44
+ - [How to gradually roll out Capacitor Live Updates](https://capawesome.io/blog/how-to-gradually-roll-out-capacitor-live-updates/#update-a-bundle)
45
+ - [How to restrict Capacitor Live Updates to Native Versions](https://capawesome.io/blog/how-to-restrict-capacitor-live-updates-to-native-versions/)
46
+ - [Live Updates for Nuxt Capacitor Apps with Capawesome Cloud](https://capawesome.io/blog/live-updates-for-nuxt-capacitor/)
47
+ - [Migrating from App Center to Capawesome Cloud](https://capawesome.io/blog/migrating-from-app-center-to-capawesome-cloud/)
48
+
19
49
  ## Installation
20
50
 
21
51
  ```bash
@@ -27,11 +57,13 @@ npx cap sync
27
57
 
28
58
  #### Variables
29
59
 
30
- This plugin will use the following project variables (defined in your app’s `variables.gradle` file):
60
+ If needed, you can define the following project variable in your app’s `variables.gradle` file to change the default version of the dependency:
31
61
 
32
- - `$okhttp3Version` version of `com.squareup.okhttp3:okhttp` (default: `22.3.1`)
62
+ - `$okhttp3Version` version of `com.squareup.okhttp3:okhttp` (default: `5.3.2`)
33
63
  - `$zip4jVersion` version of `net.lingala.zip4j:zip4j` (default: `2.11.5`)
34
64
 
65
+ This can be useful if you encounter dependency conflicts with other plugins in your project.
66
+
35
67
  ### iOS
36
68
 
37
69
  #### Privacy manifest
@@ -66,17 +98,17 @@ We recommend to declare [`CA92.1`](https://developer.apple.com/documentation/bun
66
98
  <docgen-config>
67
99
  <!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
68
100
 
69
- | Prop | Type | Description | Default | Since |
70
- | ----------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | ----- |
71
- | **`appId`** | <code>string</code> | The app ID is used to identify the app when using [Capawesome Cloud](https://capawesome.io/cloud). This is **NOT** the same as the app identifier (e.g. `com.example.app`). This is a unique identifier generated by Capawesome Cloud (e.g. `6e351b4f-69a7-415e-a057-4567df7ffe94`). | | 5.0.0 |
72
- | **`autoDeleteBundles`** | <code>boolean</code> | Whether or not to automatically delete unused bundles. When enabled, the plugin will automatically delete unused bundles after calling `ready()`. | <code>false</code> | 5.0.0 |
73
- | **`defaultChannel`** | <code>string</code> | The default channel of the app. | | 6.3.0 |
74
- | **`enabled`** | <code>boolean</code> | Whether or not the plugin is enabled. | <code>true</code> | 5.0.0 |
75
- | **`httpTimeout`** | <code>number</code> | The timeout in milliseconds for HTTP requests. | <code>60000</code> | 6.4.0 |
76
- | **`location`** | <code>'us' \| 'eu'</code> | The location of the server to use when using [Capawesome Cloud](https://capawesome.io/cloud). | <code>'us'</code> | 6.2.0 |
77
- | **`publicKey`** | <code>string</code> | The public key to verify the integrity of the bundle. The public key must be a PEM-encoded RSA public key. | | 6.1.0 |
78
- | **`readyTimeout`** | <code>number</code> | The timeout in milliseconds to wait for the app to be ready before resetting to the default bundle. | <code>10000</code> | 5.0.0 |
79
- | **`resetOnUpdate`** | <code>boolean</code> | Whether or not the app should be reset to the default bundle during an update. | <code>true</code> | 5.0.0 |
101
+ | Prop | Type | Description | Default | Since |
102
+ | -------------------------------- | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | ----- |
103
+ | **`appId`** | <code>string</code> | The app ID is used to identify the app when using [Capawesome Cloud](https://capawesome.io/cloud/). This is **NOT** the same as the app identifier (e.g. `com.example.app`). This is a unique identifier generated by Capawesome Cloud (e.g. `6e351b4f-69a7-415e-a057-4567df7ffe94`). | | 5.0.0 |
104
+ | **`autoBlockRolledBackBundles`** | <code>boolean</code> | Whether or not to automatically block bundles that have been rolled back. When enabled, the plugin will automatically block bundles that caused a rollback (up to 100 bundles). When the limit is reached, the oldest blocked bundle is unblocked. Blocked bundles will be skipped in future sync operations. **Attention**: This option has no effect if `readyTimeout` is set to `0`. Only available on Android and iOS. | <code>false</code> | 7.3.0 |
105
+ | **`autoDeleteBundles`** | <code>boolean</code> | Whether or not to automatically delete unused bundles. When enabled, the plugin will automatically delete unused bundles after calling `ready()`. | <code>false</code> | 5.0.0 |
106
+ | **`autoUpdateStrategy`** | <code>'none' \| 'background'</code> | The auto-update strategy for live updates. - `none`: Live updates will not be applied automatically. - `background`: Live updates will be automatically downloaded and applied in the background at app startup and when the app resumes (if the last check was more than 15 minutes ago). Only available on Android and iOS. | <code>'none'</code> | 7.3.0 |
107
+ | **`defaultChannel`** | <code>string</code> | The default channel of the app. | | 6.3.0 |
108
+ | **`httpTimeout`** | <code>number</code> | The timeout in milliseconds for HTTP requests. | <code>60000</code> | 6.4.0 |
109
+ | **`publicKey`** | <code>string</code> | The public key to verify the integrity of the bundle. The public key must be a PEM-encoded RSA public key. | | 6.1.0 |
110
+ | **`readyTimeout`** | <code>number</code> | The timeout in milliseconds to wait for the app to be ready before resetting to the default bundle. It is strongly **recommended** to configure this option (e.g. `10000` ms) so that the plugin can roll back to the default bundle in case of problems. If configured, the plugin will wait for the app to call the `ready()` method before resetting to the default bundle. Set to `0` to disable the timeout. | <code>0</code> | 5.0.0 |
111
+ | **`serverDomain`** | <code>string</code> | The API domain of the [Capawesome Cloud](https://cloud.capawesome.io) server **without** scheme or path. | <code>'api.cloud.capawesome.io'</code> | 7.0.0 |
80
112
 
81
113
  ### Examples
82
114
 
@@ -87,14 +119,14 @@ In `capacitor.config.json`:
87
119
  "plugins": {
88
120
  "LiveUpdate": {
89
121
  "appId": '6e351b4f-69a7-415e-a057-4567df7ffe94',
122
+ "autoBlockRolledBackBundles": undefined,
90
123
  "autoDeleteBundles": undefined,
124
+ "autoUpdateStrategy": 'background',
91
125
  "defaultChannel": 'production',
92
- "enabled": undefined,
93
126
  "httpTimeout": undefined,
94
- "location": 'eu',
95
127
  "publicKey": '-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDodf1SD0OOn6hIlDuKBza0Ed0OqtwyVJwiyjmE9BJaZ7y8ZUfcF+SKmd0l2cDPM45XIg2tAFux5n29uoKyHwSt+6tCi5CJA5Z1/1eZruRRqABLonV77KS3HUtvOgqRLDnKSV89dYZkM++NwmzOPgIF422mvc+VukcVOBfc8/AHQIDAQAB-----END PUBLIC KEY-----',
96
- "readyTimeout": undefined,
97
- "resetOnUpdate": undefined
128
+ "readyTimeout": 10000,
129
+ "serverDomain": 'api.cloud.capawesome.eu'
98
130
  }
99
131
  }
100
132
  }
@@ -111,14 +143,14 @@ const config: CapacitorConfig = {
111
143
  plugins: {
112
144
  LiveUpdate: {
113
145
  appId: '6e351b4f-69a7-415e-a057-4567df7ffe94',
146
+ autoBlockRolledBackBundles: undefined,
114
147
  autoDeleteBundles: undefined,
148
+ autoUpdateStrategy: 'background',
115
149
  defaultChannel: 'production',
116
- enabled: undefined,
117
150
  httpTimeout: undefined,
118
- location: 'eu',
119
151
  publicKey: '-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDodf1SD0OOn6hIlDuKBza0Ed0OqtwyVJwiyjmE9BJaZ7y8ZUfcF+SKmd0l2cDPM45XIg2tAFux5n29uoKyHwSt+6tCi5CJA5Z1/1eZruRRqABLonV77KS3HUtvOgqRLDnKSV89dYZkM++NwmzOPgIF422mvc+VukcVOBfc8/AHQIDAQAB-----END PUBLIC KEY-----',
120
- readyTimeout: undefined,
121
- resetOnUpdate: undefined,
152
+ readyTimeout: 10000,
153
+ serverDomain: 'api.cloud.capawesome.eu',
122
154
  },
123
155
  },
124
156
  };
@@ -128,17 +160,6 @@ export default config;
128
160
 
129
161
  </docgen-config>
130
162
 
131
- ## Starter templates
132
-
133
- The following starter templates are available:
134
-
135
- - [Ionstarter Angular Firebase](https://ionstarter.dev/)
136
- - [Ionstarter Angular SQLite](https://ionstarter.dev/)
137
-
138
- ## Guides
139
-
140
- - [Announcing the Capacitor Live Update Plugin](https://capawesome.io/blog/announcing-the-capacitor-live-update-plugin/)
141
-
142
163
  ## Usage
143
164
 
144
165
  ```typescript
@@ -197,7 +218,16 @@ const getVersionName = async () => {
197
218
  };
198
219
 
199
220
  const ready = async () => {
200
- await LiveUpdate.ready();
221
+ const result = await LiveUpdate.ready();
222
+ if (result.currentBundleId) {
223
+ console.log(`The app is now using the bundle with the identifier ${result.currentBundleId}.`);
224
+ }
225
+ if (result.previousBundleId) {
226
+ console.log(`The app was using the bundle with the identifier ${result.previousBundleId}.`);
227
+ }
228
+ if (result.rollback) {
229
+ console.log('The app was reset to the default bundle.');
230
+ }
201
231
  };
202
232
 
203
233
  const reload = async () => {
@@ -209,7 +239,7 @@ const reset = async () => {
209
239
  };
210
240
 
211
241
  const setChannel = async () => {
212
- await LiveUpdate.setChannel({ channel: 'beta' });
242
+ await LiveUpdate.setChannel({ channel: 'production-5' });
213
243
  };
214
244
 
215
245
  const setCustomId = async () => {
@@ -217,18 +247,22 @@ const setCustomId = async () => {
217
247
  };
218
248
 
219
249
  const setNextBundle = async () => {
220
- await LiveUpdate.setNextBundle({ bundleId: '1.0.0' });
250
+ await LiveUpdate.setNextBundle({ bundleId: '7f0b9bf2-dff6-4be2-bcac-b068cc5ea756' });
221
251
  };
222
252
 
223
253
  const sync = async () => {
224
- const result = await LiveUpdate.sync();
254
+ const result = await LiveUpdate.sync({
255
+ channel: 'production-5',
256
+ });
225
257
  return result.nextBundleId;
226
258
  };
227
259
 
228
260
  const isNewBundleAvailable = async () => {
229
- const { bundleId: latestBundleId } = await LiveUpdate.fetchLatestBundle();
261
+ const { bundleId: latestBundleId } = await LiveUpdate.fetchLatestBundle({
262
+ channel: 'production-5',
263
+ });
230
264
  if (latestBundleId) {
231
- const { bundleId: currentBundleId } = await LiveUpdate.getBundle();
265
+ const { bundleId: currentBundleId } = await LiveUpdate.getCurrentBundle();
232
266
  return latestBundleId !== currentBundleId;
233
267
  } else {
234
268
  return false;
@@ -240,33 +274,61 @@ const isNewBundleAvailable = async () => {
240
274
 
241
275
  <docgen-index>
242
276
 
277
+ * [`clearBlockedBundles()`](#clearblockedbundles)
243
278
  * [`deleteBundle(...)`](#deletebundle)
244
279
  * [`downloadBundle(...)`](#downloadbundle)
245
280
  * [`fetchLatestBundle(...)`](#fetchlatestbundle)
246
- * [`getBundle()`](#getbundle)
281
+ * [`getBlockedBundles()`](#getblockedbundles)
247
282
  * [`getBundles()`](#getbundles)
248
283
  * [`getChannel()`](#getchannel)
284
+ * [`getConfig()`](#getconfig)
285
+ * [`getDownloadedBundles()`](#getdownloadedbundles)
249
286
  * [`getCurrentBundle()`](#getcurrentbundle)
250
287
  * [`getCustomId()`](#getcustomid)
251
288
  * [`getDeviceId()`](#getdeviceid)
289
+ * [`isSyncing()`](#issyncing)
252
290
  * [`getNextBundle()`](#getnextbundle)
253
291
  * [`getVersionCode()`](#getversioncode)
254
292
  * [`getVersionName()`](#getversionname)
255
293
  * [`ready()`](#ready)
256
294
  * [`reload()`](#reload)
257
295
  * [`reset()`](#reset)
258
- * [`setBundle(...)`](#setbundle)
296
+ * [`resetConfig()`](#resetconfig)
259
297
  * [`setChannel(...)`](#setchannel)
298
+ * [`setConfig(...)`](#setconfig)
260
299
  * [`setCustomId(...)`](#setcustomid)
261
300
  * [`setNextBundle(...)`](#setnextbundle)
262
301
  * [`sync(...)`](#sync)
302
+ * [`addListener('downloadBundleProgress', ...)`](#addlistenerdownloadbundleprogress-)
303
+ * [`addListener('nextBundleSet', ...)`](#addlistenernextbundleset-)
304
+ * [`addListener('reloaded', ...)`](#addlistenerreloaded-)
305
+ * [`removeAllListeners()`](#removealllisteners)
263
306
  * [Interfaces](#interfaces)
307
+ * [Type Aliases](#type-aliases)
264
308
 
265
309
  </docgen-index>
266
310
 
267
311
  <docgen-api>
268
312
  <!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
269
313
 
314
+ ### clearBlockedBundles()
315
+
316
+ ```typescript
317
+ clearBlockedBundles() => Promise<void>
318
+ ```
319
+
320
+ Clear all blocked bundles from the blocked list.
321
+
322
+ This removes all bundle identifiers that were automatically blocked
323
+ due to rollbacks when `autoBlockRolledBackBundles` is enabled.
324
+
325
+ Only available on Android and iOS.
326
+
327
+ **Since:** 7.4.0
328
+
329
+ --------------------
330
+
331
+
270
332
  ### deleteBundle(...)
271
333
 
272
334
  ```typescript
@@ -326,19 +388,22 @@ Only available on Android and iOS.
326
388
  --------------------
327
389
 
328
390
 
329
- ### getBundle()
391
+ ### getBlockedBundles()
330
392
 
331
393
  ```typescript
332
- getBundle() => Promise<GetBundleResult>
394
+ getBlockedBundles() => Promise<GetBlockedBundlesResult>
333
395
  ```
334
396
 
335
- Get the active bundle identifier.
397
+ Get all blocked bundle identifiers.
398
+
399
+ Returns the list of bundle identifiers that were automatically blocked
400
+ due to rollbacks when `autoBlockRolledBackBundles` is enabled.
336
401
 
337
402
  Only available on Android and iOS.
338
403
 
339
- **Returns:** <code>Promise&lt;<a href="#getbundleresult">GetBundleResult</a>&gt;</code>
404
+ **Returns:** <code>Promise&lt;<a href="#getblockedbundlesresult">GetBlockedBundlesResult</a>&gt;</code>
340
405
 
341
- **Since:** 5.0.0
406
+ **Since:** 7.4.0
342
407
 
343
408
  --------------------
344
409
 
@@ -377,6 +442,43 @@ Only available on Android and iOS.
377
442
  --------------------
378
443
 
379
444
 
445
+ ### getConfig()
446
+
447
+ ```typescript
448
+ getConfig() => Promise<GetConfigResult>
449
+ ```
450
+
451
+ Get the runtime configuration.
452
+
453
+ Returns the current plugin configuration including any runtime
454
+ overrides set via `setConfig()`.
455
+
456
+ Only available on Android and iOS.
457
+
458
+ **Returns:** <code>Promise&lt;<a href="#getconfigresult">GetConfigResult</a>&gt;</code>
459
+
460
+ **Since:** 7.4.0
461
+
462
+ --------------------
463
+
464
+
465
+ ### getDownloadedBundles()
466
+
467
+ ```typescript
468
+ getDownloadedBundles() => Promise<GetDownloadedBundlesResult>
469
+ ```
470
+
471
+ Get all identifiers of bundles that have been downloaded.
472
+
473
+ Only available on Android and iOS.
474
+
475
+ **Returns:** <code>Promise&lt;<a href="#getdownloadedbundlesresult">GetDownloadedBundlesResult</a>&gt;</code>
476
+
477
+ **Since:** 7.4.0
478
+
479
+ --------------------
480
+
481
+
380
482
  ### getCurrentBundle()
381
483
 
382
484
  ```typescript
@@ -429,6 +531,23 @@ Only available on Android and iOS.
429
531
  --------------------
430
532
 
431
533
 
534
+ ### isSyncing()
535
+
536
+ ```typescript
537
+ isSyncing() => Promise<IsSyncingResult>
538
+ ```
539
+
540
+ Check whether a sync operation is currently in progress.
541
+
542
+ Only available on Android and iOS.
543
+
544
+ **Returns:** <code>Promise&lt;<a href="#issyncingresult">IsSyncingResult</a>&gt;</code>
545
+
546
+ **Since:** 7.4.0
547
+
548
+ --------------------
549
+
550
+
432
551
  ### getNextBundle()
433
552
 
434
553
  ```typescript
@@ -456,6 +575,9 @@ getVersionCode() => Promise<GetVersionCodeResult>
456
575
 
457
576
  Get the version code of the app.
458
577
 
578
+ On **Android**, this is the `versionCode` from the `android/app/build.gradle` file.
579
+ On **iOS**, this is the `CFBundleVersion` from the `Info.plist` file.
580
+
459
581
  Only available on Android and iOS.
460
582
 
461
583
  **Returns:** <code>Promise&lt;<a href="#getversioncoderesult">GetVersionCodeResult</a>&gt;</code>
@@ -473,6 +595,9 @@ getVersionName() => Promise<GetVersionNameResult>
473
595
 
474
596
  Get the version name of the app.
475
597
 
598
+ On **Android**, this is the `versionName` from the `android/app/build.gradle` file.
599
+ On **iOS**, this is the `CFBundleShortVersionString` from the `Info.plist` file.
600
+
476
601
  Only available on Android and iOS.
477
602
 
478
603
  **Returns:** <code>Promise&lt;<a href="#getversionnameresult">GetVersionNameResult</a>&gt;</code>
@@ -485,7 +610,7 @@ Only available on Android and iOS.
485
610
  ### ready()
486
611
 
487
612
  ```typescript
488
- ready() => Promise<void>
613
+ ready() => Promise<ReadyResult>
489
614
  ```
490
615
 
491
616
  Notify the plugin that the app is ready to use and no rollback is needed.
@@ -495,6 +620,8 @@ to prevent the app from being reset to the default bundle.
495
620
 
496
621
  Only available on Android and iOS.
497
622
 
623
+ **Returns:** <code>Promise&lt;<a href="#readyresult">ReadyResult</a>&gt;</code>
624
+
498
625
  **Since:** 5.0.0
499
626
 
500
627
  --------------------
@@ -532,23 +659,20 @@ Only available on Android and iOS.
532
659
  --------------------
533
660
 
534
661
 
535
- ### setBundle(...)
662
+ ### resetConfig()
536
663
 
537
664
  ```typescript
538
- setBundle(options: SetBundleOptions) => Promise<void>
665
+ resetConfig() => Promise<void>
539
666
  ```
540
667
 
541
- Set the next bundle to use for the app.
668
+ Reset the runtime configuration to the values from the Capacitor config file.
542
669
 
543
- Call `reload()` or restart the app to apply the changes.
670
+ This clears any runtime configuration set via `setConfig()`.
671
+ The changes take effect immediately.
544
672
 
545
673
  Only available on Android and iOS.
546
674
 
547
- | Param | Type |
548
- | ------------- | ------------------------------------------------------------- |
549
- | **`options`** | <code><a href="#setbundleoptions">SetBundleOptions</a></code> |
550
-
551
- **Since:** 5.0.0
675
+ **Since:** 7.4.0
552
676
 
553
677
  --------------------
554
678
 
@@ -572,6 +696,32 @@ Only available on Android and iOS.
572
696
  --------------------
573
697
 
574
698
 
699
+ ### setConfig(...)
700
+
701
+ ```typescript
702
+ setConfig(options: SetConfigOptions) => Promise<void>
703
+ ```
704
+
705
+ Set the runtime configuration.
706
+
707
+ This allows updating plugin configuration options at runtime.
708
+ The changes are persisted across app restarts and take effect immediately.
709
+
710
+ **Important:** Runtime configuration is automatically reset to default values
711
+ whenever the native app is updated to a new version. This ensures that
712
+ configuration from previous versions doesn't persist after an app update.
713
+
714
+ Only available on Android and iOS.
715
+
716
+ | Param | Type |
717
+ | ------------- | ------------------------------------------------------------- |
718
+ | **`options`** | <code><a href="#setconfigoptions">SetConfigOptions</a></code> |
719
+
720
+ **Since:** 7.4.0
721
+
722
+ --------------------
723
+
724
+
575
725
  ### setCustomId(...)
576
726
 
577
727
  ```typescript
@@ -635,6 +785,95 @@ Only available on Android and iOS.
635
785
  --------------------
636
786
 
637
787
 
788
+ ### addListener('downloadBundleProgress', ...)
789
+
790
+ ```typescript
791
+ addListener(eventName: 'downloadBundleProgress', listenerFunc: DownloadBundleProgressListener) => Promise<PluginListenerHandle>
792
+ ```
793
+
794
+ Listen for the download progress of a bundle.
795
+
796
+ Only available on Android and iOS.
797
+
798
+ | Param | Type |
799
+ | ------------------ | ----------------------------------------------------------------------------------------- |
800
+ | **`eventName`** | <code>'downloadBundleProgress'</code> |
801
+ | **`listenerFunc`** | <code><a href="#downloadbundleprogresslistener">DownloadBundleProgressListener</a></code> |
802
+
803
+ **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
804
+
805
+ **Since:** 7.0.0
806
+
807
+ --------------------
808
+
809
+
810
+ ### addListener('nextBundleSet', ...)
811
+
812
+ ```typescript
813
+ addListener(eventName: 'nextBundleSet', listenerFunc: NextBundleSetListener) => Promise<PluginListenerHandle>
814
+ ```
815
+
816
+ Listen for when a bundle is set as the next bundle.
817
+
818
+ This event is triggered whenever a bundle is set to be used on the next app restart,
819
+ either through automatic updates or manual calls to `setNextBundle()`.
820
+
821
+ Only available on Android and iOS.
822
+
823
+ | Param | Type |
824
+ | ------------------ | ----------------------------------------------------------------------- |
825
+ | **`eventName`** | <code>'nextBundleSet'</code> |
826
+ | **`listenerFunc`** | <code><a href="#nextbundlesetlistener">NextBundleSetListener</a></code> |
827
+
828
+ **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
829
+
830
+ **Since:** 7.3.0
831
+
832
+ --------------------
833
+
834
+
835
+ ### addListener('reloaded', ...)
836
+
837
+ ```typescript
838
+ addListener(eventName: 'reloaded', listenerFunc: ReloadedListener) => Promise<PluginListenerHandle>
839
+ ```
840
+
841
+ Listen for when the app is reloaded.
842
+
843
+ This event is triggered after the `reload()` method is called
844
+ and the app has been reloaded.
845
+
846
+ **Note:** To verify whether an update was successfully applied after a reload,
847
+ use the `ready()` method instead. The `ready()` method provides detailed information
848
+ about the current bundle, previous bundle, and whether a rollback occurred.
849
+
850
+ Only available on Android and iOS.
851
+
852
+ | Param | Type |
853
+ | ------------------ | ------------------------------------------------------------- |
854
+ | **`eventName`** | <code>'reloaded'</code> |
855
+ | **`listenerFunc`** | <code><a href="#reloadedlistener">ReloadedListener</a></code> |
856
+
857
+ **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
858
+
859
+ **Since:** 7.4.0
860
+
861
+ --------------------
862
+
863
+
864
+ ### removeAllListeners()
865
+
866
+ ```typescript
867
+ removeAllListeners() => Promise<void>
868
+ ```
869
+
870
+ Remove all listeners for this plugin.
871
+
872
+ **Since:** 7.2.0
873
+
874
+ --------------------
875
+
876
+
638
877
  ### Interfaces
639
878
 
640
879
 
@@ -647,21 +886,25 @@ Only available on Android and iOS.
647
886
 
648
887
  #### DownloadBundleOptions
649
888
 
650
- | Prop | Type | Description | Default | Since |
651
- | ------------------ | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ----- |
652
- | **`artifactType`** | <code>'manifest' \| 'zip'</code> | The artifact type of the bundle. | <code>'zip'</code> | 6.6.0 |
653
- | **`bundleId`** | <code>string</code> | The unique identifier of the bundle. | | 5.0.0 |
654
- | **`checksum`** | <code>string</code> | The checksum of the bundle to verify the integrity of the ZIP file. Must be a SHA-256 hash in base64 format. | | 6.1.0 |
655
- | **`url`** | <code>string</code> | The URL of the bundle to download. For the `zip` artifact type, the URL must point to a ZIP file. For the `manifest` artifact type, the URL serves as the base URL to download the individual files. For example, if the URL is `https://example.com/download`, the plugin will download the file with the href `index.html` from `https://example.com/download?href=index.html`. To **verify the integrity** of the file, the server must return a `X-Checksum` header with the SHA-256 hash in base64 format. To **verify the signature** of the file, the server must return a `X-Signature` header with the signed SHA-256 hash in base64 format. | | 5.0.0 |
889
+ | Prop | Type | Description | Default | Since |
890
+ | ------------------ | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ----- |
891
+ | **`artifactType`** | <code>'manifest' \| 'zip'</code> | The artifact type of the bundle. | <code>'zip'</code> | 6.6.0 |
892
+ | **`bundleId`** | <code>string</code> | The unique identifier of the bundle. **Attention**: The value `public` is reserved and cannot be used as a bundle identifier. | | 5.0.0 |
893
+ | **`checksum`** | <code>string</code> | The checksum of the self-hosted bundle as a SHA-256 hash in base64 format to verify the integrity of the bundle. **Attention**: Only supported for the `zip` artifact type. | | 7.1.0 |
894
+ | **`signature`** | <code>string</code> | The signature of the self-hosted bundle as a signed SHA-256 hash in base64 format to verify the integrity of the bundle. **Attention**: Only supported for the `zip` artifact type. | | 7.1.0 |
895
+ | **`url`** | <code>string</code> | The URL of the bundle to download. For the `zip` artifact type, the URL must point to a ZIP file. For the `manifest` artifact type, the URL serves as the base URL to download the individual files. For example, if the URL is `https://example.com/download`, the plugin will download the file with the href `index.html` from `https://example.com/download?href=index.html`. To **verify the integrity** of the file, the server should return a `X-Checksum` header with the SHA-256 hash in base64 format. To **verify the signature** of the file, the server should return a `X-Signature` header with the signed SHA-256 hash in base64 format. | | 5.0.0 |
656
896
 
657
897
 
658
898
  #### FetchLatestBundleResult
659
899
 
660
- | Prop | Type | Description | Since |
661
- | ------------------ | -------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ----- |
662
- | **`artifactType`** | <code>'manifest' \| 'zip'</code> | The artifact type of the bundle. | 6.7.0 |
663
- | **`bundleId`** | <code>string \| null</code> | The unique identifier of the latest bundle. If `null`, no bundle is available. | 6.6.0 |
664
- | **`downloadUrl`** | <code>string</code> | The URL of the latest bundle to download. Pass this URL to the `downloadBundle(...)` method to download the bundle. | 6.7.0 |
900
+ | Prop | Type | Description | Since |
901
+ | ---------------------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
902
+ | **`artifactType`** | <code>'manifest' \| 'zip'</code> | The artifact type of the bundle. | 6.7.0 |
903
+ | **`bundleId`** | <code>string \| null</code> | The unique identifier of the latest bundle. If `null`, no bundle is available. | 6.6.0 |
904
+ | **`checksum`** | <code>string</code> | The checksum of the latest bundle if the bundle is self-hosted. If the bundle is hosted on Capawesome Cloud, the checksum will be returned as response header when downloading the bundle. | 7.1.0 |
905
+ | **`customProperties`** | <code>{ [key: string]: string; }</code> | Custom properties that are associated with the latest bundle. | 7.0.0 |
906
+ | **`downloadUrl`** | <code>string</code> | The URL of the latest bundle to download. Pass this URL to the `downloadBundle(...)` method to download the bundle. | 6.7.0 |
907
+ | **`signature`** | <code>string</code> | The signature of the latest bundle if the bundle is self-hosted. If the bundle is hosted on Capawesome Cloud, the signature will be returned as response header when downloading the bundle. | 7.1.0 |
665
908
 
666
909
 
667
910
  #### FetchLatestBundleOptions
@@ -671,11 +914,11 @@ Only available on Android and iOS.
671
914
  | **`channel`** | <code>string</code> | The name of the channel where the latest bundle is fetched from. | 6.7.0 |
672
915
 
673
916
 
674
- #### GetBundleResult
917
+ #### GetBlockedBundlesResult
675
918
 
676
- | Prop | Type | Description | Since |
677
- | -------------- | --------------------------- | ---------------------------------------------------------------------------------------- | ----- |
678
- | **`bundleId`** | <code>string \| null</code> | The unique identifier of the active bundle. If `null`, the default bundle is being used. | 5.0.0 |
919
+ | Prop | Type | Description | Since |
920
+ | --------------- | --------------------- | ------------------------------------------------------ | ----- |
921
+ | **`bundleIds`** | <code>string[]</code> | An array of unique identifiers of all blocked bundles. | 7.4.0 |
679
922
 
680
923
 
681
924
  #### GetBundlesResult
@@ -692,6 +935,21 @@ Only available on Android and iOS.
692
935
  | **`channel`** | <code>string \| null</code> | The channel name. If `null`, the app is using the default channel. | 5.0.0 |
693
936
 
694
937
 
938
+ #### GetConfigResult
939
+
940
+ | Prop | Type | Description | Since |
941
+ | ------------------------ | ----------------------------------- | ------------------------------------------------------------------------ | ----- |
942
+ | **`appId`** | <code>string \| null</code> | The app ID used to identify the app. If `null`, no app ID is configured. | 7.4.0 |
943
+ | **`autoUpdateStrategy`** | <code>'none' \| 'background'</code> | The auto-update strategy for live updates. | 7.4.0 |
944
+
945
+
946
+ #### GetDownloadedBundlesResult
947
+
948
+ | Prop | Type | Description | Since |
949
+ | --------------- | --------------------- | --------------------------------------------------------- | ----- |
950
+ | **`bundleIds`** | <code>string[]</code> | An array of unique identifiers of all downloaded bundles. | 7.4.0 |
951
+
952
+
695
953
  #### GetCurrentBundleResult
696
954
 
697
955
  | Prop | Type | Description | Since |
@@ -713,6 +971,13 @@ Only available on Android and iOS.
713
971
  | **`deviceId`** | <code>string</code> | The unique identifier of the device. On iOS, [`identifierForVendor`](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor) is used. The value of this property is the same for apps that come from the same vendor running on the same device. | 5.0.0 |
714
972
 
715
973
 
974
+ #### IsSyncingResult
975
+
976
+ | Prop | Type | Description | Since |
977
+ | ------------- | -------------------- | -------------------------------------------------- | ----- |
978
+ | **`syncing`** | <code>boolean</code> | Whether a sync operation is currently in progress. | 7.4.0 |
979
+
980
+
716
981
  #### GetNextBundleResult
717
982
 
718
983
  | Prop | Type | Description | Since |
@@ -734,11 +999,13 @@ Only available on Android and iOS.
734
999
  | **`versionName`** | <code>string</code> | The version name of the app. On **Android**, this is the `versionName` from the `android/app/build.gradle` file. On **iOS**, this is the `CFBundleShortVersionString` from the `Info.plist` file. | 5.0.0 |
735
1000
 
736
1001
 
737
- #### SetBundleOptions
1002
+ #### ReadyResult
738
1003
 
739
- | Prop | Type | Description | Since |
740
- | -------------- | ------------------- | ------------------------------------------- | ----- |
741
- | **`bundleId`** | <code>string</code> | The unique identifier of the bundle to use. | 5.0.0 |
1004
+ | Prop | Type | Description | Since |
1005
+ | ---------------------- | --------------------------- | --------------------------------------------------------------------------------------- | ----- |
1006
+ | **`previousBundleId`** | <code>string \| null</code> | The identifier of the previous bundle used. If `null`, the default bundle was used. | 7.0.0 |
1007
+ | **`currentBundleId`** | <code>string \| null</code> | The identifier of the current bundle used. If `null`, the default bundle is being used. | 7.0.0 |
1008
+ | **`rollback`** | <code>boolean</code> | Whether or not the app was reset to the default bundle. | 7.0.0 |
742
1009
 
743
1010
 
744
1011
  #### SetChannelOptions
@@ -748,6 +1015,13 @@ Only available on Android and iOS.
748
1015
  | **`channel`** | <code>string \| null</code> | The channel name. Set `null` to remove the channel. | 5.0.0 |
749
1016
 
750
1017
 
1018
+ #### SetConfigOptions
1019
+
1020
+ | Prop | Type | Description | Since |
1021
+ | ----------- | --------------------------- | ----------------------------------------------------------------------------------------------------- | ----- |
1022
+ | **`appId`** | <code>string \| null</code> | The app ID used to identify the app. Set `null` to reset to the value from the Capacitor config file. | 7.4.0 |
1023
+
1024
+
751
1025
  #### SetCustomIdOptions
752
1026
 
753
1027
  | Prop | Type | Description | Since |
@@ -775,11 +1049,63 @@ Only available on Android and iOS.
775
1049
  | ------------- | ------------------- | ---------------------------------------------------------------- | ----- |
776
1050
  | **`channel`** | <code>string</code> | The name of the channel where the latest bundle is fetched from. | 6.7.0 |
777
1051
 
1052
+
1053
+ #### PluginListenerHandle
1054
+
1055
+ | Prop | Type |
1056
+ | ------------ | ----------------------------------------- |
1057
+ | **`remove`** | <code>() =&gt; Promise&lt;void&gt;</code> |
1058
+
1059
+
1060
+ #### DownloadBundleProgressEvent
1061
+
1062
+ Event that is triggered when the download progress of a bundle changes.
1063
+
1064
+ | Prop | Type | Description | Since |
1065
+ | --------------------- | ------------------- | ----------------------------------------------------------------------- | ----- |
1066
+ | **`bundleId`** | <code>string</code> | The unique identifier of the bundle that is being downloaded. | 7.0.0 |
1067
+ | **`downloadedBytes`** | <code>number</code> | The number of bytes that have been downloaded. | 7.0.0 |
1068
+ | **`progress`** | <code>number</code> | The progress of the download in percent as a value between `0` and `1`. | 7.0.0 |
1069
+ | **`totalBytes`** | <code>number</code> | The total number of bytes to download. | 7.0.0 |
1070
+
1071
+
1072
+ #### NextBundleSetEvent
1073
+
1074
+ Event that is triggered when a bundle is set as the next bundle.
1075
+
1076
+ | Prop | Type | Description | Since |
1077
+ | -------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------- | ----- |
1078
+ | **`bundleId`** | <code>string \| null</code> | The unique identifier of the bundle that is set as the next bundle. If `null`, the default bundle will be used. | 7.3.0 |
1079
+
1080
+
1081
+ ### Type Aliases
1082
+
1083
+
1084
+ #### DownloadBundleProgressListener
1085
+
1086
+ Listener for the download progress of a bundle.
1087
+
1088
+ <code>(event: <a href="#downloadbundleprogressevent">DownloadBundleProgressEvent</a>): void</code>
1089
+
1090
+
1091
+ #### NextBundleSetListener
1092
+
1093
+ Listener for when a bundle is set as the next bundle.
1094
+
1095
+ <code>(event: <a href="#nextbundlesetevent">NextBundleSetEvent</a>): void</code>
1096
+
1097
+
1098
+ #### ReloadedListener
1099
+
1100
+ Listener for when the app is reloaded.
1101
+
1102
+ <code>(): void</code>
1103
+
778
1104
  </docgen-api>
779
1105
 
780
1106
  ## Testing
781
1107
 
782
- When testing the plugin, you must make sure that you do not use the [Live Reload](https://ionicframework.com/docs/cli/livereload) option, as in this case a development server is used to load the bundle.
1108
+ When testing the plugin, you must make sure that you do not use the [Live Reload](https://ionicframework.com/docs/cli/livereload) option, as in this case a development server is used to load the bundle and not the local file system.
783
1109
 
784
1110
  Therefore, simply start your app without the live reload option, for example with the following command:
785
1111
 
@@ -787,7 +1113,17 @@ Therefore, simply start your app without the live reload option, for example wit
787
1113
  npx ionic cap run android --open
788
1114
  ```
789
1115
 
790
- If you want to disable the plugin to test other parts of your app, you can set the [`enabled`](#configuration) configuration option to `false`.
1116
+ If you want to **not** receive live updates to test other parts of your app, you can simply set a non-existent channel, for example:
1117
+
1118
+ ```typescript
1119
+ import { LiveUpdate } from '@capawesome/capacitor-live-update';
1120
+
1121
+ const sync = async () => {
1122
+ await LiveUpdate.sync({ channel: 'non-existent-channel' });
1123
+ };
1124
+ ```
1125
+
1126
+ This way, the app will check for updates, but no updates will be found.
791
1127
 
792
1128
  ## Limitations
793
1129
 
@@ -804,10 +1140,10 @@ So if you make local changes to your app and execute `npx cap run`, for example,
804
1140
  You then have three options to get back to the default bundle:
805
1141
 
806
1142
  1. **Reset**: Call the [`reset()`](#reset) method to reset the app to the default bundle.
807
- 2. **Reinstall**: Reinstall the app to use the default bundle.
808
- 3. **Update**: Increase the `versionCode`/`CFBundleVersion` so that the plugin automatically performs a reset (assuming the [`resetOnUpdate`](#configuration) configuration option is active).
1143
+ 2. **Reinstall**: Reinstall the app to remove the live update bundle.
1144
+ 3. **Update**: Increase the native version code of your app so that Capacitor automatically resets to the default bundle.
809
1145
 
810
- However, this is only a problem during development. It is not a problem in production as long as you have the [`resetOnUpdate`](#configuration) configuration option enabled, as the `versionCode`/`CFBundleVersion` is always incremented during a native update and thus always resets to the default bundle.
1146
+ However, this is only a problem during development. It is not a problem in production, as Capacitor automatically resets to the default bundle after a native update.
811
1147
 
812
1148
  ## Changelog
813
1149