Fermer

mars 21, 2024

Faites décoller vos applications Flutter avec Pigeon Platform Chaînes / Blogs / Perficient

Faites décoller vos applications Flutter avec Pigeon Platform Chaînes / Blogs / Perficient


Flutter est un excellent framework pour le développement multiplateforme. Il vous permet de créer des applications au pixel près générées dans du code natif, mais que se passe-t-il si vous devez utiliser directement le code existant dans iOS ou Android ? Pour de telles situations, Flutter vous permet d’utiliser les canaux de la plateforme.

Les canaux de plateforme vous donnent accès à des API spécifiques à la plateforme dans un langage qui fonctionne directement avec ces API. Ceux-ci sont disponibles pour Kotlin ou Java sur Android, Swift ou Objective-C sur iOS, C++ sur Windows, Objective-C sur macOS et C sur Linux.

Plus d’informations peuvent être trouvées à ce sujet ici https://docs.flutter.dev/platform-integration/platform-channels

Les API de plateforme fournies par Flutter fonctionnent comme prévu, mais l’ensemble du processus est un peu lourd à mettre en place. Pigeon nous permet d’utiliser la sécurité des types et la génération de code pour rendre ce processus beaucoup plus simple.

Créer un plugin Pigeon

Nous allons continuer et créer un exemple simple d’API.

Commençons par créer un nouveau plugin appelé exemple_pigeon

flutter create –org com.example –template=plugin –platforms=android,ios,linux,macos,windows -i swift pigeon_example Ensuite, nous allons le package pigeon

flutter pub ajouter un pigeon

et courir

flutter pub obtenir

pour télécharger le package

Types de canaux de plate-forme dans Swift

Vous trouverez ci-dessous une liste des types pris en charge dans Dard et leurs équivalents rapides. Nous utiliserons certains des types les plus courants dans notre exemple

Types de fléchettesTypes rapides
nulnéant
bouffonNSNumber(valeur : Bool)
intNSNumber(valeur : Int32)
int, si 32 bits ne suffisent pasNSNumber(valeur : Int)
doubleNSNumber(valeur : Double)
ChaîneChaîne
Liste Uint8FlutterStandardTypedData (octets : données)
Liste Int32FlutterStandardTypedData (int32 : données)
Liste Int64FlutterStandardTypedData (int64 : données)
Liste Float32FlutterStandardTypedData (float32 : données)
Liste Float64FlutterStandardTypedData (float64 : données)
ListeTableau
CarteDictionnaire

Définir notre API

Afin de faire savoir à Pigeon quelles méthodes nous allons exposer, nous définissons notre API dans une classe Dart abstraite avec le @HôteApi() décorateur, et ses méthodes

Définissons notre API Pigeon Sample dans un nouveau répertoire nommé pigeons.

import 'package:pigeon/pigeon.dart';

@HostApi()

abstract class ExampleApi {
bool getBool();
String getString();
func toggleValue();
}

Générer le code de la plateforme Pigeon

Maintenant, nous pouvons laisser le package Pigeon faire sa magie et générer du code.

dart run pigeon \
--input pigeons/example_api.dart \
--dart_out lib/example_api.dart \
--experimental_swift_out ios/Classes/ExampleApi.swift \
--kotlin_out ./android/app/src/main/kotlin/com/example/ExampleApi.kt \
--java_package "io.flutter.plugins"

Assurez-vous que les chemins d’accès à tous les fichiers sont corrects, sinon les étapes suivantes ne fonctionneront pas. Générez le code avec la sortie pour les plates-formes nécessaires. Cet exemple va se concentrer sur l’utilisation de Swift.

Ajouter une implémentation de méthode au Runner

Ensuite, nous devons écrire notre implémentation native de nos méthodes. Ce faisant, nous devons ajouter nos fichiers au coureur dans Xcode pour garantir qu’ils fonctionnent correctement.

class ExampleApiImpl : ExampleApi{
var value = true;

func getBool(){
return value;
}
func toggleValue(){
    value = !value
  }
func getString(){
return "THIS IS AN EXAMPLE";
}

}

Ajouter le canal Pigeon Platform à AppDelegate

Vous devrez également ajouter ce code dans votre AppDelegate.swift déposer

@UIApplicationMain

@objc class AppDelegate: FlutterAppDelegate {

override func application(

_ application: UIApplication,

didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?

) -> Bool {

GeneratedPluginRegistrant.register(with: self)

let exampleApi = ExampleApiImpl()

let controller : FlutterViewController = window?.rootViewController as! FlutterViewController

ExampleApiSetup.setUp(binaryMessenger: controller.binaryMessenger, api: exampleApi)




return super.application(application, didFinishLaunchingWithOptions: launchOptions)

}

}

Vous devriez maintenant pouvoir utiliser votre API dans le code Dart.

import 'package:flutter/material.dart';
import 'package:pigeon_example/example_api.dart';
import 'dart:async';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final exampleApi = ExampleApi();
  bool value = false;
  @override
  void initState() {
    super.initState();
    initPlatformState();
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    // Platform messages may fail, so we use a try/catch PlatformException.
    // We also handle the message potentially returning null.
    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            appBar: AppBar(
              title: const Text('Plugin example app'),
            ),
            body:
                Column(mainAxisAlignment: MainAxisAlignment.center, children: [
              DefaultTextStyle(
                  style: Theme.of(context).textTheme.displayMedium!,
                  textAlign: TextAlign.center,
                  child: FutureBuilder<String>(
                    future: exampleApi
                        .getString(), // a previously-obtained Future<String> or null
                    builder:
                        (BuildContext context, AsyncSnapshot<String> snapshot) {
                      List<Widget> children = [];
                      if (snapshot.data!.isNotEmpty) {
                        children = <Widget>[
                          Text(snapshot.data ?? ''),
                        ];
                      }
                      return Center(
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: children,
                        ),
                      );
                    },
                  )),
              Center(
                child: ElevatedButton(
                  child: const Text('Toggle Value'),
                  onPressed: () async {
                    await exampleApi.toggleValue();
                    var val = await exampleApi.getBool();
                    setState(() {
                      value = val;
                    });
                  },
                ),
              ),
              DefaultTextStyle(
                  style: Theme.of(context).textTheme.displayMedium!,
                  textAlign: TextAlign.center,
                  child: FutureBuilder<bool>(
                    future: exampleApi
                        .getBool(), // a previously-obtained Future<String> or null
                    builder:
                        (BuildContext context, AsyncSnapshot<bool> snapshot) {
                      List<Widget> children;
                      if (snapshot.data == true) {
                        children = <Widget>[
                          const Icon(
                            Icons.check_circle_outline,
                            color: Colors.green,
                            size: 60,
                          ),
                          Padding(
                            padding: const EdgeInsets.only(top: 16),
                            child: Text('Result: ${snapshot.data}'),
                          ),
                        ];
                      } else if (snapshot.data == false) {
                        children = <Widget>[
                          const Icon(
                            Icons.error_outline,
                            color: Colors.red,
                            size: 60,
                          ),
                          Padding(
                            padding: const EdgeInsets.only(top: 16),
                            child: Text('Result: ${snapshot.data}'),
                          ),
                        ];
                      } else {
                        children = const <Widget>[
                          SizedBox(
                            width: 60,
                            height: 60,
                            child: CircularProgressIndicator(),
                          ),
                          Padding(
                            padding: EdgeInsets.only(top: 16),
                            child: Text('Awaiting result...'),
                          ),
                        ];
                      }
                      return Center(
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: children,
                        ),
                      );
                    },
                  ))
            ])));
  }
}

Nous pouvons maintenant voir les valeurs de notre exemple d’API dans notre interface utilisateur Flutter. Basculer le bouton modifiera notre valeur booléenne.

Capture d'écran du simulateur Iphone 12 2024 03 21 au 12.56.11 Capture d'écran du simulateur Iphone 12 2024 03 21 au 12.56.08

Vous pouvez suivre ce même modèle pour tout type de données pris en charge par Pigeon.

Pour plus d’informations sur Perficient Solutions mobiles compétence, s’abonner sur notre blog ou contact notre équipe de solutions mobiles dès aujourd’hui !






Source link