OTA Updates
Push asset and config bundles to your Flutter app silently — no App Store or Play Store release required.
What OTA Updates does
Koolbase OTA lets you upload a .zip bundle containing assets — JSON configs, images, fonts, localization files — and deliver them silently to your app on next launch. The SDK checks for a newer bundle, downloads it in the background, verifies its integrity with a SHA-256 checksum, and makes it available to your app immediately.
Bundles are stored on Cloudflare R2 and delivered via presigned download URLs with a 1-hour expiry.
What can be updated via OTA
- ✅ JSON config files
- ✅ Images, icons, banners
- ✅ Fonts
- ✅ Localization strings
- ✅ Any arbitrary file your app knows how to consume
- ❌ Dart code or Flutter widgets (requires a store release)
- ❌ Native plugins or permissions
App Store compliance
How it works
- You upload a
.zipbundle from the Koolbase dashboard - You activate the bundle for a channel (production, staging, development)
- On next app launch, the SDK checks
GET /v1/sdk/ota/check - If a newer version exists, the SDK downloads and extracts it to the app's local documents directory
- Your app reads files from the bundle using
Koolbase.ota.readJson()orKoolbase.ota.getFilePath()
Initialization
Call Koolbase.ota.initialize() in your app startup after Koolbase.initialize(). It checks for a new bundle and downloads it automatically.
await Koolbase.initialize(const KoolbaseConfig(
publicKey: 'pk_live_xxxx',
baseUrl: 'https://api.koolbase.com',
));
// Auto-check and download on launch
final result = await Koolbase.ota.initialize(
channel: 'production', // defaults to 'production'
onProgress: (progress) {
print('OTA: ${progress.state} ${progress.progress}');
},
);
if (result.hasUpdate) {
print('Bundle v${result.version} applied');
}Mandatory vs optional updates
initialize() blocks until the download completes before returning. If optional, the download runs in the background and the bundle is available on the next launch.Reading bundle files
Once a bundle is cached, read files from it using the OTA client. If no bundle is cached, these methods return null — your app should fall back to its bundled assets.
// Read a JSON file from the active bundle
final config = await Koolbase.ota.readJson('config.json');
if (config != null) {
final welcomeText = config['welcome_text'] as String?;
final themeColor = config['theme_color'] as String?;
}
// Get the file path for images or other assets
final bannerPath = await Koolbase.ota.getFilePath('banner.png');
if (bannerPath != null) {
// Use File(bannerPath) in your widget
}Manual check
You can manually trigger a check at any point — for example, when the app comes back to the foreground.
// Check without downloading
final result = await Koolbase.ota.check(channel: 'production');
if (result.hasUpdate) {
print('New bundle available: v${result.version}');
print('Mandatory: ${result.mandatory}');
print('Size: ${result.fileSize} bytes');
// Download manually
final success = await Koolbase.ota.download(
result,
onProgress: (p) => print('${p.state}'),
);
}Bundle management
// Check if a bundle is currently cached
final hasCached = await Koolbase.ota.hasCachedBundle;
// Get the current cached version number (0 if none)
final version = await Koolbase.ota.currentVersion;
// Clear the cached bundle (resets to app defaults)
await Koolbase.ota.clearBundle();Dashboard workflow
- Go to your project → OTA Updates
- Click Upload Bundle and select your
.zipfile - Choose the target channel and whether the update is mandatory
- After upload, click the Activate button (▶) on the bundle row
- The SDK will pick up the new bundle on the next app launch
Rollback
Bundle format
A bundle is a standard .zip file. You can include any files your app needs. The SDK searches for files both at the root level and one directory deep (to handle zips that include a root folder).
# Example bundle structure
my_bundle/
├── config.json # App config
├── banner.png # Marketing image
├── strings_en.json # Localization
└── theme.json # Theme config
# Create the bundle
zip -r my_bundle_v2.zip my_bundle/Maximum bundle size is 50MB.
API reference
| Method | Description |
|---|---|
Koolbase.ota.initialize() | Auto-check and download on launch. Blocks if mandatory. |
Koolbase.ota.check() | Check server for a newer bundle. Returns OtaCheckResult. |
Koolbase.ota.download(result) | Download, verify, and extract a bundle. |
Koolbase.ota.readJson(filename) | Read a JSON file from the active bundle. |
Koolbase.ota.getFilePath(filename) | Get the absolute path to a file in the bundle. |
Koolbase.ota.hasCachedBundle | Returns true if a bundle is cached on device. |
Koolbase.ota.currentVersion | Returns the cached bundle version number. |
Koolbase.ota.clearBundle() | Delete the cached bundle and reset to defaults. |