Démarrage rapide en 5 minutes
Ce guide vous accompagne pas à pas pour intégrer le SDK tk_ota_push dans votre application Flutter, configurer le filtrage RemoteConfigGatekeeper et déployer votre premier patch à chaud.
Étape 1 : Créer le fichier shorebird.yaml
À la racine de votre projet Flutter (au même niveau que pubspec.yaml), créez le fichier shorebird.yaml :
# Identifiant de l'Organisation Multi-Tenant
tenant_id: sara-money
# Identifiant de l'Application Mobile (optionnel si détecté depuis Gradle/Xcode)
app_id: com.saramoney.app
# URL du serveur OTA souverain (lue par la CLI et par le moteur Rust mobile)
base_url: https://ota.saramoney.internal
# Canal de distribution par défaut
channel: stable
# Délègue le déclenchement réseau au Gatekeeper Dart en 3 étapes
auto_update: false
# Vérification cryptographique RSA-SHA256 à chaque démarrage
patch_verification: strict
# Clé publique RSA (synchronisée automatiquement par tk-ota-push release/patch)
patch_public_key: MIIBCgKCAQEA...
Vérifiez que shorebird.yaml est bien référencé dans pubspec.yaml :
dependencies:
flutter:
sdk: flutter
tk_ota_push: ^1.0.0
flutter:
assets:
- shorebird.yaml
Étape 2 : Initialiser TkOtaPush dans lib/main.dart
Voici un fichier lib/main.dart complet et fonctionnel intégrant :
- L'initialisation de
TkOtaPush.init(...)avec le bouclier de sécurité et la détection de rollback. - L'évaluation du payload Remote Config via
syncWithRemoteConfig(...). - L'affichage d'une modale bloquante lorsque
force_update: true. - La lecture de l'identité de l'appareil (
readDeviceIdentity()) pour le support technique.
import 'package:flutter/material.dart';
import 'package:tk_ota_push/tk_ota_push.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 1. Initialisation du SDK mobile tk_ota_push
final ota = TkOtaPush.init(
appReleaseVersion: '1.0.0+1',
enableGatekeeper: true,
requireWifiForSilentUpdate: false,
minBatteryPercentageForSilentUpdate: 20,
securityPolicy: const OtaSecurityPolicy(
blockRootedOrJailbrokenDevices: true,
expectedApkSignaturesSha256: {
// Remplacez par l'empreinte SHA-256 de votre keystore de production
'6b6929c8ff345cf008496328d7bff081a8ccfb89498bf9916ed668be3c3dedcf',
},
),
onRollbackDetected: (event) async {
debugPrint(
'Rollback détecté sur ${event.releaseVersion} : '
'#${event.previousPatchNumber} -> #${event.restoredPatchNumber}',
);
// Purgez ici vos caches locaux (SQLite / SharedPreferences) si nécessaire
},
onSecurityViolation: (verdict) async {
debugPrint('Violation de sécurité OTA : ${verdict.reason}');
},
);
// 2. Récupération du payload Remote Config (Firebase, API interne, etc.)
final remoteConfigJson = <String, dynamic>{
'target_release_version': '1.0.0+1',
'patch_available': true,
'latest_patch_number': 1,
'force_update': false,
'release_notes': 'Optimisation du parcours de virement.',
};
// 3. Synchronisation intelligente en 3 étapes (0 appel réseau si déjà à jour)
final outcome = await ota.syncWithRemoteConfig(
OtaRemoteConfig.fromJson(remoteConfigJson),
);
debugPrint('Mode exécuté : ${outcome.executionMode.name} (${outcome.message})');
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'TkushPatch Quickstart',
home: Scaffold(
appBar: AppBar(title: const Text('Statut OTA TkushPatch')),
body: FutureBuilder<OtaDeviceIdentity?>(
future: TkOtaPush.instance.readDeviceIdentity(),
builder: (context, snapshot) {
final identity = snapshot.data;
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Version Release : ${TkOtaPush.instance.appReleaseVersion}'),
const SizedBox(height: 8),
Text('Patch actif : #${identity?.currentPatchNumber ?? 0}'),
const SizedBox(height: 8),
Text('Code Support N3 : ${identity?.shortSupportCode ?? "En attente"}'),
const SizedBox(height: 8),
Text('Canal : ${TkOtaPush.instance.track.name}'),
],
),
);
},
),
),
);
}
}
Étape 3 : Publier la Release de référence
Avant de pouvoir envoyer des patchs différentiels, vous devez compiler et verrouiller la Release de base correspondant à la version distribuée aux utilisateurs (1.0.0+1 dans pubspec.yaml) :
# 1. Authentification auprès du serveur TkushPatch
tk-ota-push login
# 2. Compilation et verrouillage de la Release de r éférence
tk-ota-push release -p android
Lors de cette commande, la CLI :
- Récupère automatiquement la clé publique RSA du serveur (
GET /api/admin/v1/public-key) et l'écrit dansshorebird.yamlsouspatch_public_key. - Compile l'application en mode release avec la toolchain Shorebird (
--obfuscateactivé par défaut). - Extrait le binaire
binaire d'applicationdirectement depuis l'APK/AAB final et scelle son empreinte SHA-256 ainsi que l'empreinte du code natif (NativeIntegrityScanner) sur le serveur.
Étape 4 : Déployer votre premier Patch OTA
Modifiez maintenant un texte ou une logique métier en code Dart dans lib/main.dart sans incrémenter la version dans pubspec.yaml, puis exécutez :
tk-ota-push patch -p android -m "Premier correctif à chaud"
Le serveur calcule le différentiel binaire (différentiel binaire + compression optimisée), signe le condensat SHA-256 du binaire cible avec la clé privée RSA hébergée dans moteur de signature et publie le Patch #1.
Au prochain appel de syncWithRemoteConfig avec patch_available: true et latest_patch_number: 1 :
- Les 3 conditions du
RemoteConfigGatekeeperpassent au vert (GatekeeperVerdict.allowed). - Le SDK appelle
checkAndUpdate(), télécharge le micro-patch et vérifie sa signature RSA-SHA256. - Au redémarrage suivant de l'application (Cold Start), le Patch
#1est immédiatement actif.