Desarrollando paquetes & Plugins
Introducción a los paquetes
Los paquetes permiten la creación de código modular que puede ser compartido fácilmente. Un paquete mínimo consiste en:
-
Un fichero
pubspec.yaml: Un fichero de metadatos que declara el nombre del paquete, versión, autor, etc. -
Un directorio
libconteniendo el código público del paquete, como mínimo un único fichero<package-name>.dart.
Tipos de paquetes
Los paquetes pueden contener varios tipos de contenido:
-
Paquetes Dart: Paquetes generales escritos en Dart, por ejemplo el paquete
path. Algunos de estos pueden contener funcionalidades específicas de Flutter y así tener una dependencia del framework Flutter, restringiendo su uso solo a Flutter, por ejemplo el paquetefluro. -
Paquetes de Plugin: Un paquete especializado de Dart que contiene una API escrita en código Dart combinado con una implementación específica de plataforma para Android (usando Java o Kotlin), y/o para iOS (usando ObjC o Swift). Un ejemplo concreto es el paquete de plugin
battery.
Desarrollando paquetes Dart
Paso 1: Crea el paquete
Para crear un paquete Dart, usa la etiqueta --template=package con flutter create:
$ flutter create --template=package hello
Esto crea un proyecto de paquete en la carpeta hello/ con el siguiente
contenido especializado:
-
lib/hello.dart:- El código Dart para el paquete.
-
test/hello_test.dart:- Los test unitarios para el paquete.
Paso 2: Implementa el paquete
Para paquetes Dart puros, simplemente añade la funcionalidad dentro del fichero
main dentro de lib/<package name>.dart, o en múltiples ficheros en el directorio lib.
Para probar el paquete, añade test unitarios
en el directorio test.
Para detalles adicionales sobre como organizar el contenido de un paquete, mira la documentación en Dart library package.
Desarrollar paquetes de plugin
Si quieres desarrollar un paquete que hace llamadas a APIs específicas de plataforma, necesitas desarrollar un paquete de plugin. Un paquete de plugin es una versión especializada de un paquete Dart, que además del contenido descrito anteriormente también contiene implementaciones específicas de plataforma, escritas para Android (código Java o Kotlin) o para iOS (código Objective-C o Swift), o para ambas. La API se conecta con las implementaciones específicas de plataforma usando platform channels.
Paso 1: Crea el paquete
Para crear el paquete de plugin, usa la opción --template=plugin con flutter create.
Usa la opción --org para especificar tu organización, usando notación de nombre de
dominio inversa. Este valor es usado en varios paquetes y bundle identifiers en el código
generado Android e iOS.
$ flutter create --org com.example --template=plugin hello
Esto crea un proyecto de plugin en la carpeta hello/ con el siguiente contenido
especializado:
-
lib/hello.dart:- La API dart para el plugin.
-
android/src/main/java/com/example/hello/HelloPlugin.java:- La implementación específica de la API del plugin.
-
ios/Classes/HelloPlugin.m:- La implementación ,especifica de plataforma iOS, de la API del plugin.
-
example/:- Una app Flutter app que dependa del plugin, e ilustra como usarlo.
Por defecto, el proyecto de plugin usa código Objective-C para iOS y
código Java para Android. Si prefieres Swift o Kotlin, puedes especificar el
lenguaje iOS usando -i y/o el lenguaje Android usando -a. Por ejemplo:
$ flutter create --template=plugin -i swift -a kotlin hello
Paso 2: Implementa el paquete
Como un paquete de plugin, contiene código de diversas plataformas escritos en múltiples lenguajes de programación, son necesarios algunos pasos específicos para asegurar una experiencia adecuada.
Paso 2a: Define la API del paquete (.dart)
La API del paquete de plugin es definida en código Dart. Abre la carpeta principal hello/
en tu editor Flutter favorito. Localiza el fichero
lib/hello.dart.
Paso 2b: Añade el código de la plataforma Android (.java/.kt)
Te recomendamos que edites el código Android usando Android Studio.
Después de editar el código de la plataforma Android en Android Studio, primero asegúrate que
el código ha sido compilado al menos una vez (ej., ejecuta la app de ejemplo desde tu IDE/editor,
o en terminal ejecuta cd hello/example; flutter build apk).
A continuación,
- Lanza Android Studio
- Selecciona ‘Import project’ en el diálogo ‘Welcome to Android Studio’, o selecciona
‘File > New > Import Project…’’ en el menú, y selecciona el fichero
hello/example/android/build.gradle. - En el diálogo ‘Gradle Sync’ , selecciona ‘OK’.
- En el diálogo ‘Android Gradle Plugin Update’, selecciona ‘Don’t remind me again for this project’.
El código de la plataforma Android de tu plugin está ubicado en
hello/java/com.example.hello/HelloPlugin.
Puedes ejecutar la app de ejemplo desde Android Studio presionando el botón ▶.
Paso 2c: Añade el código de la plataforma iOS (.h+.m/.swift)
Te recomendamos editar tu código iOS en Xcode.
Después de editar el código de la plataforma iOS en Xcode, primero asegúrate que el
código ha sido compilado al menos una vez (ej., ejecuta la app de ejemplo desde tu IDE/editor,
o en una terminal ejecuta cd hello/example; flutter build ios --no-codesign).
A continuación,
- Lanza Xcode
- Selecciona ‘File > Open’, y selecciona el fichero
hello/example/ios/Runner.xcworkspace.
El código de la plataforma iOS de tu plugin está ubicado en Pods/Development
Pods/hello/Classes/ en Project Navigator.
Puedes ejecutar la app de ejemplo presionando el botón ▶.
Paso 2d: Conecta la API y el código de plataforma
Finalmente, necesitas conectar la API escrita en código Dart con las implementaciones específicas de plataforma. Esto se consigue usando platform channels.
Añadiendo documentación
Es una práctica recomendada añadir la siguiente documentación a todos los paquetes:
- Un fichero
README.mdque hace de introducción al paquete - Un fichero
CHANGELOG.mdque documenta los cambios en cada versión - Un fichero
LICENSEconteniendo los términos bajo los que el paquete es licensiado - Documentación de la API para todas las APIs públicas (mira abajo para más detalles)
Documentación de API
Cuando publicas un paquete, la documentación de la API es generada y publicada automáticamente a dartdocs.org, mira por ejemplo la documentación de device_info.
Si quieres generar documentación de la API localmente en tu máquina de desarrollo , usa los siguientes comandos:
-
Cambia al directorio en que está ubicado tu paquete:
cd ~/dev/mypackage -
Di a la herramienta de documentación donde esta el SDK de Flutter ( cámbialo para reflejar donde está ubicado):
export FLUTTER_ROOT=~/dev/flutter(en macOS o Linux)set FLUTTER_ROOT=~/dev/flutter(en Windows) -
Ejecuta la herramienta
dartdoc(que viene como parte del SDK de Flutter):$FLUTTER_ROOT/bin/cache/dart-sdk/bin/dartdoc(en macOS o Linux)%FLUTTER_ROOT%\bin\cache\dart-sdk\bin\dartdoc(en Windows)
Para consejos sobre como escribir la documentación de la API, mira Effective Dart: Documentation.
Añadir licencias al fichero LICENSE
Cada licencia individual dentro del fichero LICENSE deben separarse por una de 80 guiones.
Si un fichero de LICENSE contiene más de una licensia de componente, cada licencia de componente debe empezar con el nombre del paquete al que se aplica esta licencia de componente, con cada nombre de paquete en su propia linea, y la lista de nombres de paquetes separadas del texto de la licencia actual por una línea en blanco. (Los paquete deben coincidir con el nombre del paquete en pub. Por ejemplo, un paquete puede contener código de múltiples fuentes de terceros, y debe incluir una licencia para cada uno.)
Good:
package_1
<some license text>
--------------------------------------------------------------------------------
package_2
<some license text>
Also good:
package_1
<some license text>
--------------------------------------------------------------------------------
package_1
package_2
<some license text>
Bad:
<some license text>
--------------------------------------------------------------------------------
<some license text>
Also bad:
package_1
<some license text>
--------------------------------------------------------------------------------
<some license text>
Publicando paquetes
Una vez que has implementado un paquete, puedes publicarlo en Pub, para que otros desarrolladores puedan usarlo fácilmente.
Antes de publicar, asegúrate de revisar el pubspec.yaml, README.md, y
CHANGELOG.md para estar seguro de que su contenido está completo y es correcto.
A continuación, ejecuta el comando dry-run para ver si todos los análisis pasan correctamente:
$ flutter pub pub publish --dry-run
(Fijate en la redundancia pub pub, que es necesaria mientras el [issue #33302)(https://github.com/flutter/flutter/issues/33302) es resuelto).
Finalmente, ejecuta el comando actual para publicar:
$ flutter pub publish
Para detales sobre publicación, mira Pub publishing docs.
Manejando interdependencias entre paquetes
Si has desarrollado el paquete hello que depende de la API Dart expuesta por otro paquete,
necesitas añadir este paquete a la sección dependencies en tu fichero pubspec.yaml.
El código a continuación hace que la API Dart del plugin url_launcher esté disponible para hello:
En hello/pubspec.yaml:
dependencies:
url_launcher: ^0.4.2
Ahora puedes hacer import 'package:url_launcher/url_launcher.dart' y launch(someUrl) en
el código Dart de hello.
Esto no es diferente de como incluyes paquetes en aplicaciones Flutter o en cualquier otro proyecto Dart.
Pero si hello resulta ser un paquete de plugin cuyo código específico de plataforma necesita acceso al código
específico de plataforma de la API expuesta por url_launcher, también necesitas añadir declaraciones
de dependencia adecuadas a tus archivos de compilación específicos de plataforma, como mostramos abajo.
Android
En hello/android/build.gradle:
android {
// varias líneas saltadas
dependencies {
provided rootProject.findProject(":url_launcher")
}
}
Ahora puedes hacer import io.flutter.plugins.urllauncher.UrlLauncherPlugin y acceder a la clase
UrlLauncherPlugin en el código fuente en hello/android/src.
iOS
En hello/ios/hello.podspec:
Pod::Spec.new do |s|
# varias líneas saltadas
s.dependency 'url_launcher'
Ahora puedes hacer #import "UrlLauncherPlugin.h" y acceder a la clase UrlLauncherPlugin
en el código fuente en hello/ios/Classes.

