Flutter SDK
If your app is using Flutter the SDK helps you to easily integrate appcockpit.dev.
Links
Functionality
Versions
Whenever the SDK detects a new version it will show an alert or UI component informing the user and ask them to update. Optional updates can be dismissed — once dismissed, the same version won't be shown again (persisted via SharedPreferences).
Maintenance mode
When maintenance mode is active, the SDK displays a full-screen overlay blocking access to the app and periodically re-checks until maintenance ends.
Installation
Add to your pubspec.yaml:
dependencies:
appcockpit: ^1.0.0
Then run:
flutter pub get
Setup
-
Make sure you followed the Getting started guide
-
Copy your
API Tokenfrom the app settings
Quick Start
import 'package:appcockpit/appcockpit.dart';
const appInfo = AppInfo(
platform: 'ios',
appId: '<appcockpit_app_id>',
appstoreId: '123456789',
appVersion: '2.5.0',
environment: 'production',
userId: '12345', // optional
);
const maintenanceInfo = MaintenanceInfo(
appId: '<appcockpit_app_id>',
environment: 'production',
);
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MaintenanceWrapper(
info: maintenanceInfo,
apiToken: 'your-api-token',
child: AppUpdateWrapper(
info: appInfo,
apiToken: 'your-api-token',
child: const YourApp(),
),
),
);
}
}
Pre-built update version UI
For a streamlined integration, you can use the pre-built update UI widget that handles version checking and update prompts automatically.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
info | AppInfo | Yes | App configuration |
apiToken | String | Yes | API authentication token |
child | Widget | Yes | The child widget to display |
customUpdateScreen | CustomUpdateScreenBuilder | No | Custom update screen builder |
languageKey | String | No | Language for localized strings (defaults to 'en') |
buttonTheme | UpdateButtonTheme | No | Theme customization for the update button |
import 'package:appcockpit/appcockpit.dart';
class MyApp extends StatelessWidget {
final info = const AppInfo(
platform: 'ios', // or 'android'
appId: '<appcockpit_app_id>',
appstoreId: '<app_store_id>',
appVersion: '1.0.0',
environment: 'production',
);
final apiToken = '<api_token>';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: AppUpdateWrapper(
info: info,
apiToken: apiToken,
// Optional theme for the update button:
buttonTheme: const UpdateButtonTheme(
backgroundColor: Color(0xFFFF0000),
textColor: Color(0xFFFFFFFF),
),
child: const AppContent(),
),
);
}
}
The AppUpdateWrapper automatically handles:
- Version checking on app startup
- Displaying update prompts when needed
- Managing force update scenarios (non-dismissible)
- Redirecting to app stores for updates
- Persisting dismissed optional updates via SharedPreferences
Custom update version UI
You can customize the update screen by providing your own builder via the customUpdateScreen parameter, or omit it to use the default update UI.
import 'package:appcockpit/appcockpit.dart';
AppUpdateWrapper(
info: appInfo,
apiToken: 'your-api-token',
customUpdateScreen: (context, versionInfo, appInfo, onUpdate, onClose) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('New version: ${versionInfo.version}'),
ElevatedButton(onPressed: onUpdate, child: const Text('Update')),
if (!versionInfo.forceUpdate)
TextButton(onPressed: onClose, child: const Text('Later')),
],
),
),
);
},
child: const YourApp(),
)
Important callbacks:
onUpdate(): Call this when the user wants to update. The SDK will redirect to the app store.onClose(): Call this when the user dismisses the update (only available for non-forced updates).
Standalone Version Check
For cases where you don't want to use the AppUpdateWrapper widget (e.g., custom flows or triggered checks), you can use the checkVersionUpdate function directly. It checks for updates and shows a native AlertDialog instead of the full-screen modal.
import 'package:appcockpit/appcockpit.dart';
await checkVersionUpdate(
context,
appInfo,
'your-api-token',
languageKey: 'en',
);
- Force updates show a non-dismissible alert that reopens after pressing "Update Now".
- Optional updates can be dismissed. Dismissed versions are persisted via SharedPreferences.
Pre-built maintenance mode UI
For a streamlined maintenance mode integration, you can use the pre-built maintenance UI widget that handles maintenance checking and display automatically.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
info | MaintenanceInfo | Yes | App ID and environment |
apiToken | String | Yes | API authentication token |
child | Widget | Yes | The child widget to display |
customMaintenanceScreen | CustomMaintenanceScreenBuilder | No | Custom maintenance screen builder |
theme | MaintenanceTheme | No | Theme customization |
import 'package:appcockpit/appcockpit.dart';
class MyApp extends StatelessWidget {
final info = const MaintenanceInfo(
appId: '<appcockpit_app_id>',
environment: 'production',
);
final apiToken = '<api_token>';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MaintenanceWrapper(
info: info,
apiToken: apiToken,
// Optional theme for the maintenance screen:
theme: const MaintenanceTheme(
backgroundColor: Color(0xFF1a1a2e),
titleColor: Color(0xFFFFFFFF),
messageColor: Color(0xFFCCCCCC),
linkColor: Color(0xFF4ea8de),
),
child: const AppContent(),
),
);
}
}
The MaintenanceWrapper automatically handles:
- Maintenance mode checking on app startup
- Displaying maintenance screen when maintenance mode is active
- Blocking app access during maintenance
- Periodic re-checking until maintenance ends
The maintenance response may include links (e.g., status page, social media) that are rendered as tappable cards.
Custom maintenance mode UI
You can customize the maintenance screen by providing your own customMaintenanceScreen builder, or omit it to use the default maintenance UI.
import 'package:appcockpit/appcockpit.dart';
MaintenanceWrapper(
info: maintenanceInfo,
apiToken: 'your-api-token',
customMaintenanceScreen: (context, maintenanceInfo) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(maintenanceInfo.title ?? 'Under Maintenance'),
Text(maintenanceInfo.description ?? 'Please check back soon.'),
],
),
),
);
},
child: const YourApp(),
)
Types
AppInfo
class AppInfo {
final String platform; // 'ios' or 'android'
final String appId; // Your app identifier (e.g., bundle ID)
final String appstoreId; // App Store ID (iOS) or package name (Android)
final String appVersion; // Current app version (e.g., '2.5.0')
final String environment; // Deployment environment (e.g., 'production')
final String? userId; // Optional user ID for tracking
}
MaintenanceInfo
class MaintenanceInfo {
final String appId;
final String environment;
}
VersionResponse
class VersionResponse {
final String version;
final String platform;
final bool forceUpdate;
final String? defaultUpdateMessage;
final Map<String, String>? updateMessages;
}
MaintenanceResponse
class MaintenanceResponse {
final bool active;
final String? title;
final String? description;
final List<MaintenanceLink>? links;
}
class MaintenanceLink {
final String title;
final String url;
}
Language Support
The SDK supports 20 languages for built-in update prompts. Pass a language key to AppUpdateWrapper or checkVersionUpdate:
AppUpdateWrapper(
info: appInfo,
apiToken: 'your-api-token',
languageKey: 'de',
child: const YourApp(),
)
If no language is specified, the SDK defaults to English.
The API can also return custom update_messages per language, which take priority over the built-in defaults.
| Key | Language |
|---|---|
'en' | English |
'es' | Spanish |
'fr' | French |
'de' | German |
'it' | Italian |
'pt' | Portuguese |
'ru' | Russian |
'ja' | Japanese |
'ko' | Korean |
'zh' | Chinese |
'ar' | Arabic |
'hi' | Hindi |
'nl' | Dutch |
'sv' | Swedish |
'da' | Danish |
'no' | Norwegian |
'fi' | Finnish |
'pl' | Polish |
'tr' | Turkish |
'he' | Hebrew |