Best Practices¶
Here are some best practices to follow when using the Live Update SDK to ensure a smooth user experience:
- Automatic Rollbacks: Automatically revert to the previous version if an update fails.
- Automatic Storage Cleanup: Implement a strategy for cleaning up unused or outdated bundles.
- Binary Compatible Changes: Ensure that your updates are binary compatible to avoid breaking changes.
- Code Signing: Sign your app bundles to ensure their integrity and authenticity.
- Reasonable Update Checks: Implement a strategy for checking for updates without using too many device resources.
Automatic Rollbacks¶
The Live Update SDK supports automatic rollbacks in case an invalid bundle is provided. To enable this feature, you first need to configure the readyTimeout
configuration option in your Capacitor project. This option specifies the maximum amount of time to wait for the app to be ready before rolling back to the built-in app bundle.
We recommend setting the readyTimeout
to a value that balances user experience and the need for timely updates. A value of 10,000 milliseconds (10 seconds) is a good starting point. The app now has a maximum of 10 seconds to call the ready()
method before the SDK rolls back to the built-in app bundle. You can adjust this value based on your app's specific needs. Larger apps may require a longer timeout.
import { LiveUpdate } from "@capawesome/capacitor-live-update";
const initializeApp = async () => {
await LiveUpdate.ready(); // Call this method BEFORE any other Live Update methods, e.g.:
// await LiveUpdate.sync();
};
Make sure to call the ready()
method as early as possible in your app's lifecycle to ensure the SDK is properly initialized and ready to handle updates. For example, in Angular, you could call this method directly in the constructor of your AppComponent
.
Automatic Storage Cleanup¶
Since each billing plan includes a fixed quota of storage space, it is important to implement a strategy for automatically cleaning up unused or outdated bundles to avoid exceeding this limit. There are two main approaches to achieve this:
Both approaches can be used either individually or in combination.
Bundle Expiration Dates¶
The first approach is to set expiration dates for your bundles. This ensures that outdated bundles are automatically removed after a certain period of time. For example, you can use the following Capawesome CLI command to create a bundle that expires after 365 days:
In most cases, such a long expiration period is enough to ensure that users have ample time to update their apps before the bundles are removed.
Channel Bundle Limits¶
The second approach is to set limits on the number of bundles that can be stored for each channel. This ensures that older bundles are automatically removed when the limit is reached. For example, you can use the following Capawesome CLI command to create a channel with a bundle limit of 3:
As soon as the limit of 3 bundles is reached, the oldest bundle will be automatically removed to make room for the new one.
Binary Compatible Changes¶
It is important to make sure that only Binary Compatible Changes are delivered to your users to prevent incompatible updates.
Capawesome Cloud offers two different ways to restrict live updates to specific native versions:
- Versioned Bundles
- Versioned Channels (recommended)
Versioned Bundles¶
Versioned bundles allow you to restrict live updates to specific native versions by defining a range of version codes for each platform.
Version Code
The version code (named versionCode
on Android and CFBundleVersion
on iOS) is the internal version number of your app. It is used to determine whether one version is more recent than another and must be incremented each time you release a new version of your app.
To create a versioned bundle, you only need to specify the minimum and maximum version codes for each platform:
- Minimum Version: The native binary must have at least this version code to be compatible with the bundle.
- Maximum Version: The native binary must have at most this version code to be compatible with the bundle.
For this, you can use the following Capawesome CLI command:
Versioned Channels¶
Versioned channels allow you to restrict live updates to specific native versions by creating a channel for each version code. This is the recommended approach, as it leaves less room for mistakes and makes bundles easier to manage. Channels also offer advanced features such as bundle limits.
To create a versioned channel, you can use the following Capawesome CLI command:
In this example, we created a channel named production-10
for the version code 10
.
To upload a bundle to a specific channel, you can use the following Capawesome CLI command:
Finally, we just need to set the correct channel in the app to ensure that only compatible bundles are downloaded:
import { LiveUpdate } from '@capawesome/capacitor-live-update';
const sync = async () => {
// Get the version code of the native app
const { versionCode } = await LiveUpdate.getVersionCode();
// Automatically download and set the latest compatible bundle
await LiveUpdate.sync({ channel: `production-${versionCode}` });
};
Code Signing¶
We strongly recommend signing your app bundles to ensure their integrity and authenticity. This way, you can be sure that the bundles have not been tampered with and are coming from a trusted source. For more information, check out the Code Signing guide.
Reasonable Update Checks¶
While it's important to keep your app up-to-date, checking for updates too frequently can lead to a poor user experience. Not only does the device get rate-limited after a certain number of requests, but these requests also use up a lot of the device's resources like battery and data.
You should definitely NOT check for updates in fixed intervals, such as every few seconds:
import { LiveUpdate } from "@capawesome/capacitor-live-update";
// Do NOT do this!!!
setTimeout(() => {
LiveUpdate.checkForUpdate();
}, 60000);
Instead, we recommend implementing a reasonable update strategy that balances the need for timely updates with the overall user experience. Check out the Always Latest update strategy for an example of how to achieve this.