Aller au contenu principal

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 :

  1. Récupère automatiquement la clé publique RSA du serveur (GET /api/admin/v1/public-key) et l'écrit dans shorebird.yaml sous patch_public_key.
  2. Compile l'application en mode release avec la toolchain Shorebird (--obfuscate activé par défaut).
  3. Extrait le binaire binaire d'application directement 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 :

  1. Les 3 conditions du RemoteConfigGatekeeper passent au vert (GatekeeperVerdict.allowed).
  2. Le SDK appelle checkAndUpdate(), télécharge le micro-patch et vérifie sa signature RSA-SHA256.
  3. Au redémarrage suivant de l'application (Cold Start), le Patch #1 est immédiatement actif.