====== Tips, Tutos, Examples Flutter ======
===== Build optimisation =====
==== kDebugMode ====
[[https://api.flutter.dev/flutter/foundation/kDebugMode-constant.html|kDebugMode]] étant un constante, le compilateur peut supprimer du code: ''Tree Shaking''. Il faut donc l'utiliser pour réduire la taille de la compilation ''release''.
J'ai vérifié en recherchant des chaînes de caractères dans ''app-release.apk/lib/x86_64/libapp.so'' : elles ne sont pas présentent si encapsulées dans un ''if( kDebugMode ){}''
==== --split-debug-info ====
Pour compiler une release //un peu// plus légère
$ flutter build apk
23M app-release.apk
# installed: 43.19 MB
$ flutter build apk --split-debug-info=/tmp
22M app-release.apk
# installed: 42.17 MB
$ flutter build appbundle
42M app-release.aab
$ flutter build appbundle --split-debug-info=/tmp
40M app-release.aab
===== Secret Data in App =====
On ne peut pas avoir de secret stocké dans l'App, c'est certain. 😉
Par contre on peut le cacher pour le rendre plus difficile à découvrir.
flutter build apk \
--release \
--obfuscate \
--split-debug-info=./debug_info \
--dart-define=API_URL=https://myapi.com \
--dart-define=API_KEY=super_secret_key
const apiUrl = String.fromEnvironment('API_URL');
const apiKey = String.fromEnvironment('API_KEY');
Mais dans la vraie vie on préférera mettre les secrets dans un fichier, en oubliant pas d'informer ''git'' de l'ignorer.
flutter build apk \
--release \
--obfuscate \
--split-debug-info=./debug_info \
--dart-define-from-file=config.prod.json
Et le fichier config.prod.json
{
"API_URL": "https://myapi.com",
"API_KEY": "super_secret_key",
"FEATURE_X": "true",
"CLIENT_ID": "xyz-123"
}
* [[https://dev.to/alaminkarno/wait-youre-using-env-files-in-flutter-for-secrets-lets-talk-before-its-too-late-1nbf|“Wait… You’re Using .env Files in Flutter for Secrets?” Let’s Talk Before It’s Too Late]]
===== Notifications =====
Les notifications locales sont basées sur un tâche de fond périodique (Workmanager).
* La programmation de la tâche est faite au démarrage de l'App.
* Quand on tue l'App avec "Settings -> Applications -> MyApp -> Force stop (Forcer l'arrêt)", la programmation est annulée
* **TODO** confirmer (ou pas) qu'après un long temps sans utilisation de l'App et que le système la tue la programmation n'est pas conservée ...
* Quand on reboot le device, la programmation est activée automatiquement, sans besoin de relancer l'App
===== Adaptative design =====
* [[https://docs.flutter.dev/ui/adaptive-responsive/platform-adaptations|Automatic platform adaptations]]
Adaptative design phone vs tablet vs desktop:
* use of [[https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html|LayoutBuilder]]
* [[https://www.tutorialkart.com/flutter/flutter-gridview-set-crossaxiscount-based-on-width-dynamically/|How to set crossAxisCount of GridView based on Width in Flutter?]]
* use [[https://api.flutter.dev/flutter/widgets/MediaQuery-class.html|MediaQuery]]
* https://stackoverflow.com/a/63788428/4833788
* https://github.com/AmmarSAA/Flutter-Responsive-Screen
==== MediaQuery size ====
^ Device ^ width ^ height ^
| iPhone SE | 375.00 | 667.0 |
| Galaxy A41 | 411.43 | 866.29 |
| AVD small phone | 360.0 | 592.00 |
| AVD medium phone | 411.43 | 866.29 |
| AVD Pixel 8 Pro | 448.00 | 949.33 |
| AVD Pixel Tablet | 1280.00 | 800.00 |
===== ListView =====
* [[https://www.geeksforgeeks.org/flutter/flutter-fetching-json-data-using-http/|Fetching JSON Data using HTTP]]
* [[https://fluttertalk.com/flutter-listview-builder-tutorial-building-dynamic-and-customizable-lists/|ListView Builder Tutorial: Building Dynamic and Customizable Lists]]
* [[https://bendyworks.com/blog/a-month-of-flutter-rendering-a-list-view-with-stream-builder/|rendering a ListView with StreamBuilder]]
Le conteneur du ListView doit pouvoir géré que la hauteur n'est pas connue à priori, voir [[/informatique/flutter/debug#le_rendu_plante_sans_rien_dans_la_debug_console]].
===== Async =====
Différence entre ''Future'' et ''Microtask'' : [[https://fluttercurious.com/mastering-flutter-microtasks-for-optimal-performance/|Mastering Flutter Microtasks for Optimal Performance]]. En conclusion, dans l' ''Event loop'' la ''Microtask'' est prioritaire par rapport à la ''Future''.
===== Play Store =====
Voir [[https://cyrille.giquello.fr/informatique/android#deploiement_play_console|Déploiement Play Console]]
Pour notamment:
* com.android.vending.CHECK_LICENSE
* Protection automatique désactivé
Voir aussi
* build option [[#split-debug-info|--split-debug-info]]
===== App Store Connect =====
==== testeurs externes ====
Les "testeurs externes" voient les nouvelles versions après plusieurs heures/jours, tant que le build est "**//En attente de vérification//**" il ne les voient pas ... 😩
===== iOS dev =====
{{ :informatique:flutter:remmina_codemagic_simulator_20250812-061404.jpg?direct&400|Codemagic Remmina remote access}}
==== Codemagic.io ====
[[https://blog.codemagic.io/remote-access-to-virtual-mac-build-machine/|How to use remote access to Codemagic virtual MacOS build machine]], la VM reste allumée 20 minutes. 🚀 500 minutes gratuites. 🍀
clients VNC : [[https://remmina.org|Remmina]]
===== Android dev =====
3 méthodes pour [[https://jeroenmols.com/blog/2023/01/25/development-server-emulator/|Android emulator access to local server]]. Le plus simple est d'utiliser https://10.0.2.2:3000.
==== network_security_config.xml ====
Pour avoir un ''network_security_config.xml'' personnalisé:
Dans ''AndroidManifest.xml''
Ensuite dans ''android/app/src/main/res/xml/network_security_config.xml'', par exemple:
10.0.2.2
==== Deep links ====
https://codewithandrea.com/articles/flutter-deep-links/
List de tous les deep links (prefered apps) du système (émulateur) :
adb shell dumpsys package domain-preferred-apps
==== App Fingerprint ====
If you are using VS Code, open a terminal inside your project and then:
* ''cd android'' folder
* and run ''./gradlew signingReport''