Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Flutter : communication Android/iOS et les packages

Flutter : communication Android/iOS et les packages

A l'occasion de la première édition du meetup Flutter Paris, trois sessions ont été données : une introduction à Flutter, un livecode d'une application et enfin une présentation.

Dans cette dernière, la manière de communiquer avec les plateformes spécifiques (Android ou iOS) est expliquée : comment récupérer un résultat généré côté Java/Kotlin ou Objective C/Swift et le recevoir dans la partie Dart/Flutter ?

La seconde partie de la présentation concerne les dépendances d'un projet, que l'on appelle packages et plugins en Flutter.

Enfin les derniers slides relatent l'avancement de la bêta de Flutter et notamment les fonctionnalités qui arriveront prochainement.

Edouard Marquez

April 05, 2018
Tweet

More Decks by Edouard Marquez

Other Decks in Technology

Transcript

  1. 3 Flutter Paris Aller plus loin en Flutter Android /

    iOS Et maintenant ? — Comment faire communiquer son code Flutter avec Android et / ou iOS ? — Roadmap Flutter — Ressources utiles Les packages / plugins — A quoi servent-ils ? — Où les trouver ? — Comment les utiliser dans ses applications ?
  2. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Flutter et Android / iOS 5 FlutterView Dans une Activité Android FlutterViewController Dans un AppDelegate iOS
  3. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Flutter et Android / iOS 5 FlutterView Dans une Activité Android FlutterViewController Dans un AppDelegate iOS Dart runApp() Flutter
  4. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? MethodChannel : Communication avec résultat 6
  5. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? MethodChannel : Communication avec résultat 6
  6. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? MethodChannel : Communication avec résultat 6 Résultat, erreur ou non implémenté
  7. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? MethodChannel : Communication avec résultat 6 Résultat, erreur ou non implémenté Dart Android iOS null null nil / NSNull bool Boolean NSNumber numberWithBool int Integer NSNumber numberWithInt Int (> 32 bits) Long NSNumber numberWithLong Int (> 64 bits) BigInteger FlutterStandardBigInteger double Double NSNumber numberWithDouble String String NSString Uint8List byte[] FlutterStandardTypedData typedDataWithBytes: Int32List int[] FlutterStandardTypedData typedDataWithInt32: Int64List long[] FlutterStandardTypedData typedDataWithInt64: Float64List double[] FlutterStandardTypedData typedDataWithFloat64: List ArrayList NSArray Map HashMap NSDictionary
  8. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les MethodChannel côté Flutter 7 Dart On crée un MethodChannel, sur lequel on va appeler une méthode dont le résultat est asynchrone. static const MethodChannel channel = const MethodChannel('flutter.paris/test'); Future<String> getBatteryLevel() { try { int level = await channel.invokeMethod('getBatteryLevel'); return 'Battery level $level'; } on PlatformException { return "Unknown battery level"; } }
  9. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les MethodChannel côté Flutter 7 Dart On crée un MethodChannel, sur lequel on va appeler une méthode dont le résultat est asynchrone. static const MethodChannel channel = const MethodChannel('flutter.paris/test'); Future<String> getBatteryLevel() { try { int level = await channel.invokeMethod('getBatteryLevel'); return 'Battery level $level'; } on PlatformException { return "Unknown battery level"; } } Future<String> getBatteryLevel() { try { int level = await channel.invokeMethod('getBatteryLevel'); return 'Battery level $level'; } on PlatformException { return "Unknown battery level"; } }
  10. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les MethodChannel sur Android 8 Android On modifie le code de la MainActivity public class MainActivity extends FlutterActivity { public void onCreate(Bundle bundle) { super.onCreate(bundle); GeneratedPluginRegistrant.registerWith(this); // TODO } }
  11. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les MethodChannel sur Android 9 new MethodChannel(getFlutterView(), "flutter.paris/test") .setMethodCallHandler(new MethodCallHandler() { public void onMethodCall(MethodCall call, Result result) { if (call.method.equals("getBatteryLevel")) { int batteryLevel = getBatteryLevel(); if (batteryLevel != -1) { result.success(batteryLevel); } else { result.error("UNAVAILABLE", "Battery level not available.", null); } } else { result.notImplemented(); }}} );}}
  12. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les MethodChannel sur Android 9 new MethodChannel(getFlutterView(), "flutter.paris/test") .setMethodCallHandler(new MethodCallHandler() { public void onMethodCall(MethodCall call, Result result) { if (call.method.equals("getBatteryLevel")) { int batteryLevel = getBatteryLevel(); if (batteryLevel != -1) { result.success(batteryLevel); } else { result.error("UNAVAILABLE", "Battery level not available.", null); } } else { result.notImplemented(); }}} );}} if (call.method.equals("getBatteryLevel")) { int batteryLevel = getBatteryLevel(); if (batteryLevel != -1) { result.success(batteryLevel); } else { result.error("UNAVAILABLE", "Battery level not available.", null); } } else { result.notImplemented(); }}}
  13. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les MethodChannel sur Android 9 new MethodChannel(getFlutterView(), "flutter.paris/test") .setMethodCallHandler(new MethodCallHandler() { public void onMethodCall(MethodCall call, Result result) { if (call.method.equals("getBatteryLevel")) { int batteryLevel = getBatteryLevel(); if (batteryLevel != -1) { result.success(batteryLevel); } else { result.error("UNAVAILABLE", "Battery level not available.", null); } } else { result.notImplemented(); }}} );}} if (call.method.equals("getBatteryLevel")) { int batteryLevel = getBatteryLevel(); if (batteryLevel != -1) { result.success(batteryLevel); } else { result.error("UNAVAILABLE", "Battery level not available.", null); } } else { result.notImplemented(); }}} int batteryLevel = getBatteryLevel(); if (batteryLevel != -1) { result.success(batteryLevel); } else { result.error("UNAVAILABLE", "Battery level not available.", null); }
  14. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les MethodChannel sur iOS 10 iOS On modifie le code de l'AppDelegate - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { [GeneratedPluginRegistrant registerWithRegistry:self]; FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController; FlutterMethodChannel* batteryChannel = [FlutterMethodChannel methodChannelWithName:@"flutter.paris/test" binaryMessenger:controller]; // TODO return [super application:application didFinishLaunchingWithOptions:launchOptions]; }
  15. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les MethodChannel sur iOS 10 iOS On modifie le code de l'AppDelegate - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { [GeneratedPluginRegistrant registerWithRegistry:self]; FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController; FlutterMethodChannel* batteryChannel = [FlutterMethodChannel methodChannelWithName:@"flutter.paris/test" binaryMessenger:controller]; // TODO return [super application:application didFinishLaunchingWithOptions:launchOptions]; } FlutterMethodChannel* batteryChannel = [FlutterMethodChannel methodChannelWithName:@"flutter.paris/test" binaryMessenger:controller]; // TODO
  16. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les MethodChannel sur iOS 11 [batteryChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { if ([@"getBatteryLevel" isEqualToString:call.method]) { int batteryLevel = [self getBatteryLevel]; if (batteryLevel == -1) { result([FlutterError errorWithCode:@"UNAVAILABLE" message:@"Battery info unavailable" 
 details:nil]); } else { result(@(batteryLevel)); } } else { result(FlutterMethodNotImplemented); } }];
  17. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les MethodChannel sur iOS 11 [batteryChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { if ([@"getBatteryLevel" isEqualToString:call.method]) { int batteryLevel = [self getBatteryLevel]; if (batteryLevel == -1) { result([FlutterError errorWithCode:@"UNAVAILABLE" message:@"Battery info unavailable" 
 details:nil]); } else { result(@(batteryLevel)); } } else { result(FlutterMethodNotImplemented); } }]; if ([@"getBatteryLevel" isEqualToString:call.method]) { int batteryLevel = [self getBatteryLevel]; if (batteryLevel == -1) { result([FlutterError errorWithCode:@"UNAVAILABLE" message:@"Battery info unavailable" 
 details:nil]); } else { result(@(batteryLevel)); } } else { result(FlutterMethodNotImplemented); }
  18. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les MethodChannel sur iOS 11 [batteryChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { if ([@"getBatteryLevel" isEqualToString:call.method]) { int batteryLevel = [self getBatteryLevel]; if (batteryLevel == -1) { result([FlutterError errorWithCode:@"UNAVAILABLE" message:@"Battery info unavailable" 
 details:nil]); } else { result(@(batteryLevel)); } } else { result(FlutterMethodNotImplemented); } }]; if ([@"getBatteryLevel" isEqualToString:call.method]) { int batteryLevel = [self getBatteryLevel]; if (batteryLevel == -1) { result([FlutterError errorWithCode:@"UNAVAILABLE" message:@"Battery info unavailable" 
 details:nil]); } else { result(@(batteryLevel)); } } else { result(FlutterMethodNotImplemented); } int batteryLevel = [self getBatteryLevel]; if (batteryLevel == -1) { result([FlutterError errorWithCode:@"UNAVAILABLE" message:@"Battery info unavailable" 
 details:nil]); } else { result(@(batteryLevel)); }
  19. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? EventChannel : Communication avec un seul résultat 12
  20. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? EventChannel : Communication avec un seul résultat 12 Résultat(s) et/ou erreur(s)
  21. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les EventChannel côté Flutter 13 Dart On crée un EventChannel, sur lequel on va appeler une méthode dont le résultat est un Stream. static const EventChannel eventChannel = const EventChannel('flutter.paris/testEvent'); eventChannel.receiveBroadcastStream() .listen((obj) { // Nouvelle position reçue }, (err) { // Nouvelle erreur reçue } );
  22. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les EventChannel côté Flutter 13 Dart On crée un EventChannel, sur lequel on va appeler une méthode dont le résultat est un Stream. static const EventChannel eventChannel = const EventChannel('flutter.paris/testEvent'); eventChannel.receiveBroadcastStream() .listen((obj) { // Nouvelle position reçue }, (err) { // Nouvelle erreur reçue } ); eventChannel.receiveBroadcastStream() .listen((obj) { // Nouvelle valeur reçue }, onError: (err) { // Nouvelle erreur reçue } );
  23. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les EventChannel sur Android 14 Android On modifie le code de la MainActivity On met en attribut l'EventSink public class MainActivity extends FlutterActivity { public void onCreate(Bundle bundle) { super.onCreate(bundle); GeneratedPluginRegistrant.registerWith(this); }
  24. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les EventChannel sur Android 14 Android On modifie le code de la MainActivity On met en attribut l'EventSink public class MainActivity extends FlutterActivity implements StreamHandler { private EventSink sink; public void onCreate(Bundle bundle) { super.onCreate(bundle); GeneratedPluginRegistrant.registerWith(this); new EventChannel(getFlutterView(), "flutter.paris/testEvent")
 .setStreamHandler(this)); }
  25. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les EventChannel sur Android 15 @Override public void onListen(Object arguments, EventSink events) { events.success("Hello"); events.success("World"); } @Override public void onCancel(Object arguments) { this. } @Override public void onListen(Object arguments, EventSink events) { this.sink = events; events.success("Hello"); events.success("World"); } @Override public void onCancel(Object arguments) { this.sink = null;
  26. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les EventChannel sur Android 15 @Override public void onListen(Object arguments, EventSink events) { events.success("Hello"); events.success("World"); } @Override public void onCancel(Object arguments) { this. } @Override public void onListen(Object arguments, EventSink events) { this.sink = events; events.success("Hello"); events.success("World"); } @Override public void onCancel(Object arguments) { this.sink = null; this.sink = events; events.success("Hello"); events.success("World");
  27. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les EventChannel sur Android 15 @Override public void onListen(Object arguments, EventSink events) { events.success("Hello"); events.success("World"); } @Override public void onCancel(Object arguments) { this. } @Override public void onListen(Object arguments, EventSink events) { this.sink = events; events.success("Hello"); events.success("World"); } @Override public void onCancel(Object arguments) { this.sink = null; this.sink = events; events.success("Hello"); events.success("World"); this.sink = null;
  28. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les EventChannel sur iOS 16 iOS On modifie le code de l'AppDelegate On garde la variable de type FlutterEventSink pour l'appeler à n'importe quel moment @implementation AppDelegate { FlutterEventSink _eventSink; } -(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { [GeneratedPluginRegistrant registerWithRegistry:self]; FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController; FlutterEventChannel* eventChannel = [FlutterEventChannel eventChannelWithName:@"flutter.paris/testEvent" binaryMessenger:controller]; 
 [eventChannel setStreamHandler:self]; }
  29. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les EventChannel sur iOS 16 iOS On modifie le code de l'AppDelegate On garde la variable de type FlutterEventSink pour l'appeler à n'importe quel moment @implementation AppDelegate { FlutterEventSink _eventSink; } -(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { [GeneratedPluginRegistrant registerWithRegistry:self]; FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController; FlutterEventChannel* eventChannel = [FlutterEventChannel eventChannelWithName:@"flutter.paris/testEvent" binaryMessenger:controller]; 
 [eventChannel setStreamHandler:self]; } FlutterEventChannel* eventChannel = [FlutterEventChannel eventChannelWithName:@"flutter.paris/testEvent" binaryMessenger:controller];
  30. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les EventChannel sur iOS 16 iOS On modifie le code de l'AppDelegate On garde la variable de type FlutterEventSink pour l'appeler à n'importe quel moment @implementation AppDelegate { FlutterEventSink _eventSink; } -(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { [GeneratedPluginRegistrant registerWithRegistry:self]; FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController; FlutterEventChannel* eventChannel = [FlutterEventChannel eventChannelWithName:@"flutter.paris/testEvent" binaryMessenger:controller]; 
 [eventChannel setStreamHandler:self]; } @implementation AppDelegate { FlutterEventSink _eventSink; } FlutterEventChannel* eventChannel = [FlutterEventChannel eventChannelWithName:@"flutter.paris/testEvent" binaryMessenger:controller];
  31. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les EventChannel sur iOS 17 - (FlutterError*)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)eventSink { _eventSink = eventSink; _eventSink(@"Hello"); _eventSink(@"World"); return nil; } - (FlutterError*)onCancelWithArguments:(id)arguments { _eventSink = nil; return nil; } @end
  32. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les EventChannel sur iOS 17 - (FlutterError*)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)eventSink { _eventSink = eventSink; _eventSink(@"Hello"); _eventSink(@"World"); return nil; } - (FlutterError*)onCancelWithArguments:(id)arguments { _eventSink = nil; return nil; } @end _eventSink = eventSink; _eventSink(@"Hello"); _eventSink(@"World");
  33. Flutter Paris sli.do/zr8eef4g Communication Android / iOS Packages / plugins

    Et maintenant ? Les EventChannel sur iOS 17 - (FlutterError*)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)eventSink { _eventSink = eventSink; _eventSink(@"Hello"); _eventSink(@"World"); return nil; } - (FlutterError*)onCancelWithArguments:(id)arguments { _eventSink = nil; return nil; } @end _eventSink = eventSink; _eventSink(@"Hello"); _eventSink(@"World"); _eventSink = nil;
  34. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g A quoi servent-ils ? 19
  35. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g A quoi servent-ils ? 19 Nouveaux widgets Nouveaux composants graphiques Outils tiers Firebase, MixPanel… Nouveau composants Redux, RXDart… Compléter des fonctions Ex: demander la géolocalisation du téléphone
  36. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Quelle différence entre package et plugin ? 20 Package Ne contient que du code Dart (dossier lib)
  37. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Quelle différence entre package et plugin ? 21 Android Code Java/Kotlin (dossier android) iOS Code Obj C/Swift (dossier ios) Plugin Code Dart (dossier lib)
  38. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Où les trouver ? 22 https://pub.dartlang.org/flutter
  39. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Choisir son plugin 23
  40. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Choisir son plugin 23
  41. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Pub : le gestionnaire des dépendances 24 Le gestionnaire des dépendances du langage Dart pub Fichier dans lequel on indique les dépendances du projet pubspec.yaml Fichier généré qui précise quelles versions des dépendances sont utilisées pubspec.lock
  42. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Comment les utiliser dans vos applications ? 25 Pubspec.yaml Le fichier pubspec est en quelque sorte la carte d'identité de l'application. On y indique le nom et la description du projet, tout comme les ressources (assets) qui pourront être utilisées. On indique également les dépendances qui seront utilisées. name: helloworld description: A new Flutter project. dependencies: flutter: sdk: flutter cupertino_icons: ^0.1.0 dev_dependencies: flutter_test: sdk: flutter flutter: uses-material-design: true
  43. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Ajouter une dépendance 26 Ajouter la dépendance au projet dependencies firebase_auth: '^0.5.3'
  44. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Pubspec.yaml : indiquer le numéro de version 27 any La dernière version disponible 1.2.3 Exactement la version 1.2.3 >=1.2.3 Au moins la 1.2.3 >1.2.3 Une version supérieure à la 1.2.3 <=1.2.3 Au maximum la 1.2.3 <1.2.3 Une version antérieure à la 1.2.3
  45. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Pubspec.yaml : indiquer une plage de versions 28 Utiliser la version la plus récente entre la 0.5 et 0.9** dependencies firebase_auth: '>=0.5.3 <0.6.0'
  46. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Pubspec.yaml : indiquer une plage de versions 28 Utiliser la version la plus récente entre la 0.5 et 0.9** dependencies firebase_auth: '>=0.5.3 <0.6.0' La caret syntax permet d'exprimer une plage de versions dependencies firebase_auth: '^0.5.3'
  47. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Dépendances : la source 29
  48. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Dépendances : la source 29 Repo officiel pub.dartlang.org
  49. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Dépendances : la source 29 Repo privé Hébergé par vos soins Repo officiel pub.dartlang.org
  50. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Dépendances : la source 29 Repo privé Hébergé par vos soins Git Pointer sur une branche, 
 un tag ou un commit Repo officiel pub.dartlang.org
  51. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Dépendances : la source 29 Repo privé Hébergé par vos soins Git Pointer sur une branche, 
 un tag ou un commit Repo officiel pub.dartlang.org Dossier local
  52. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Flutter packages… : les commandes utiles 30 Récupère les dépendances pour les nouveaux packages flutter packages get Mettre à jour les dépendances flutter packages upgrade
  53. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Une sélection des packages utiles 31 Authentification Database & Cloud Firestore Storage Analytics Messaging AdMob Firebase Base de données SQLite (SQFLite) Préférences (~ NSUserDefaults) Données Flux Redux RXDart Flutter Stream Friends Autres Google Facebook Twitter Comptes
  54. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Une sélection des packages utiles 32 Graphiques (animés) Charts Flutter
  55. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Une sélection des packages utiles 32 Graphiques (animés) Charts Flutter
  56. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Une sélection des packages utiles 33 Grille avec des éléments de tailles différentes Staggered 
 Grid View De la parallaxe avec n'importe quel widget Flutter Parallax
  57. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Une sélection des packages utiles 33 Grille avec des éléments de tailles différentes Staggered 
 Grid View De la parallaxe avec n'importe quel widget Flutter Parallax
  58. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Une sélection des packages utiles 34 Moteur de jeu 2D Sprite Widget
  59. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Une sélection des packages utiles 34 Moteur de jeu 2D Sprite Widget
  60. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Roadmap (sur GitHub) 36
  61. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Roadmap (lors de l'annonce de la bêta) 37 Intégration WebView Maps Routing Taille Faciliter l'intégration de Flutter dans une application existante Enrichir/améliorer les APIs pour la navigation Intégrer des WebView dans l'arbre des widgets Intégrer une carte comme widget Réduire la taille du moteur
  62. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Roadmap (sondage) 38
  63. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Quelques ressources 39 Flutter.rocks https://flutter.rocks/ Sergi & Replace https://sergiandreplace.com Flutter institute https://flutter.institute/ Codelabs codelabs.google.com / flutter.io Flutter Weekly https://flutterweekly.net/
  64. Communication Android / iOS Packages / plugins Et maintenant ?

    Flutter Paris sli.do/zr8eef4g Extension Chrome 40