Skip to content

Commit 780fdce

Browse files
authored
feat(live-update): add native channel configuration support (#783)
* feat(live-update): add native channel configuration support * docs: add changeset * style: format
1 parent 8735550 commit 780fdce

File tree

5 files changed

+79
-1
lines changed

5 files changed

+79
-1
lines changed

.changeset/full-pigs-eat.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@capawesome/capacitor-live-update': minor
3+
---
4+
5+
feat: add native channel configuration support

packages/live-update/README.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,21 @@ npx cap sync
5151

5252
### Android
5353

54+
#### Channel
55+
56+
If you are using [Versioned Channels](https://capawesome.io/cloud/live-updates/guides/best-practices/#versioned-channels), you can set a default channel directly in your native project by adding a string resource.
57+
This allows you to tie the channel to the version code at build time.
58+
59+
Add the following to your app's `build.gradle` file:
60+
61+
```groovy
62+
android {
63+
defaultConfig {
64+
resValue "string", "capawesome_live_update_default_channel", "production-" + defaultConfig.versionCode
65+
}
66+
}
67+
```
68+
5469
#### Variables
5570

5671
If needed, you can define the following project variable in your app’s `variables.gradle` file to change the default version of the dependency:
@@ -62,6 +77,18 @@ This can be useful if you encounter dependency conflicts with other plugins in y
6277

6378
### iOS
6479

80+
#### Channel
81+
82+
If you are using [Versioned Channels](https://capawesome.io/cloud/live-updates/guides/best-practices/#versioned-channels), you can set a default channel directly in your native project by adding a key to your `Info.plist` file.
83+
This allows you to tie the channel to the build version at build time.
84+
85+
Add the following to your `Info.plist` file:
86+
87+
```xml
88+
<key>CapawesomeLiveUpdateDefaultChannel</key>
89+
<string>production-$(CURRENT_PROJECT_VERSION)</string>
90+
```
91+
6592
#### Privacy manifest
6693

6794
Add the `NSPrivacyAccessedAPICategoryUserDefaults` dictionary key to your [Privacy Manifest](https://capacitorjs.com/docs/ios/privacy-manifest) (usually `ios/App/PrivacyInfo.xcprivacy`):
@@ -100,7 +127,7 @@ We recommend to declare [`CA92.1`](https://developer.apple.com/documentation/bun
100127
| **`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 |
101128
| **`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 |
102129
| **`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 |
103-
| **`defaultChannel`** | <code>string</code> | The default channel of the app. | | 6.3.0 |
130+
| **`defaultChannel`** | <code>string</code> | The default channel of the app. This can be overridden by `setChannel()` or the `channel` parameter of `sync()`. It takes priority over the native channel configuration (`CapawesomeLiveUpdateDefaultChannel` in `Info.plist` on iOS or `capawesome_live_update_default_channel` in `strings.xml` on Android). | | 6.3.0 |
104131
| **`httpTimeout`** | <code>number</code> | The timeout in milliseconds for HTTP requests. | <code>60000</code> | 6.4.0 |
105132
| **`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 |
106133
| **`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 |
@@ -429,6 +456,15 @@ getChannel() => Promise<GetChannelResult>
429456

430457
Get the channel that is used for the update.
431458

459+
The channel is resolved in the following order (highest priority first):
460+
1. `setChannel()` (SharedPreferences on Android / UserDefaults on iOS)
461+
2. Capacitor config `defaultChannel`
462+
3. Native config (`CapawesomeLiveUpdateDefaultChannel` in `Info.plist` on iOS or
463+
`capawesome_live_update_default_channel` in `strings.xml` on Android)
464+
465+
**Note**: The `channel` parameter of `sync()` takes the highest priority
466+
but is not persisted and therefore not returned by this method.
467+
432468
Only available on Android and iOS.
433469

434470
**Returns:** <code>Promise&lt;<a href="#getchannelresult">GetChannelResult</a>&gt;</code>

packages/live-update/android/src/main/java/io/capawesome/capacitorjs/plugins/liveupdate/LiveUpdate.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,10 @@ private String getAppId() {
10121012
@Nullable
10131013
private String getChannel() {
10141014
String channel = null;
1015+
String nativeChannel = getNativeChannel();
1016+
if (nativeChannel != null) {
1017+
channel = nativeChannel;
1018+
}
10151019
if (config.getDefaultChannel() != null) {
10161020
channel = config.getDefaultChannel();
10171021
}
@@ -1021,6 +1025,18 @@ private String getChannel() {
10211025
return channel;
10221026
}
10231027

1028+
@Nullable
1029+
private String getNativeChannel() {
1030+
int resId = plugin
1031+
.getContext()
1032+
.getResources()
1033+
.getIdentifier("capawesome_live_update_default_channel", "string", plugin.getContext().getPackageName());
1034+
if (resId == 0) {
1035+
return null;
1036+
}
1037+
return plugin.getContext().getResources().getString(resId);
1038+
}
1039+
10241040
/**
10251041
* @return The current bundle ID or `null` if the default bundle is in use.
10261042
*/

packages/live-update/ios/Plugin/LiveUpdate.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,9 @@ import CommonCrypto
601601

602602
private func getChannel() -> String? {
603603
var channel: String?
604+
if let nativeChannel = getNativeChannel() {
605+
channel = nativeChannel
606+
}
604607
if let _ = config.defaultChannel {
605608
channel = config.defaultChannel
606609
}
@@ -610,6 +613,10 @@ import CommonCrypto
610613
return channel
611614
}
612615

616+
private func getNativeChannel() -> String? {
617+
return Bundle.main.object(forInfoDictionaryKey: "CapawesomeLiveUpdateDefaultChannel") as? String
618+
}
619+
613620
/// - Returns: The sha256 checksum of the file at the given URL.
614621
private func getChecksumForFile(url: URL) throws -> String {
615622
let handle = try FileHandle(forReadingFrom: url)

packages/live-update/src/definitions.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ declare module '@capacitor/cli' {
5757
/**
5858
* The default channel of the app.
5959
*
60+
* This can be overridden by `setChannel()` or the `channel` parameter of `sync()`.
61+
* It takes priority over the native channel configuration
62+
* (`CapawesomeLiveUpdateDefaultChannel` in `Info.plist` on iOS or `capawesome_live_update_default_channel`
63+
* in `strings.xml` on Android).
64+
*
6065
* @since 6.3.0
6166
* @example 'production'
6267
*/
@@ -166,6 +171,15 @@ export interface LiveUpdatePlugin {
166171
/**
167172
* Get the channel that is used for the update.
168173
*
174+
* The channel is resolved in the following order (highest priority first):
175+
* 1. `setChannel()` (SharedPreferences on Android / UserDefaults on iOS)
176+
* 2. Capacitor config `defaultChannel`
177+
* 3. Native config (`CapawesomeLiveUpdateDefaultChannel` in `Info.plist` on iOS or
178+
* `capawesome_live_update_default_channel` in `strings.xml` on Android)
179+
*
180+
* **Note**: The `channel` parameter of `sync()` takes the highest priority
181+
* but is not persisted and therefore not returned by this method.
182+
*
169183
* Only available on Android and iOS.
170184
*
171185
* @since 5.0.0

0 commit comments

Comments
 (0)