✈️

Flutterの自作パッケージを作るときに見たものをまとめた

2022/01/25に公開

Flutterのパッケージ

Flutterで開発をしていたとき、音量を取得したり操作することがしたくなりました。
しかし、pub.devを見てみてもやりたいことが実現できそうなパッケージが見つからず。。。
「ないならば自分でつくろう」となったのですが初めてのことだったので色々と調べました。
今回は自作プラグインパッケージを作るときのDay0で必要なことをまとめておこうと思います。

Flutterには2種類のパッケージがある

そもそもですが、Flutterにはパッケージと呼ばれるものが2つあります。
1つはDartパッケージ。もう1つはプラグインパッケージです。

DartパッケージはFlutterフレームワークのみを使ったパッケージです。Dartで書かれています。
DartパッケージにはFlutter固有の機能が含まれています。ルーティングなどです。

プラグインパッケージはプラットフォーム固有の実装とDartの実装を合わせたパッケージです。
例えばiOS固有の通知などを実装するといったものが挙げられます。

プラグインパッケージの作り方

公式ドキュメントに従ってプラグインパッケージを作っていきます。

flutter create --org com.example --template=plugin --platforms=android,ios -a kotlin saample

このコマンドでプラグインパッケージ用のプロジェクトを作成できます。
オプション説明
--tenmplate このオプションを浸けることでFlutterが公式に展開しているプラグインプロジェクトの雛形を使ってプロジェクトを組み上げます

--platform このオプションではプラグインパッケージが対応するプラットフォームを指定します。
AndriodとiOSに対応させたいときには --platform=andriod,iosとカンマ区切りで指定します。
-i swiftもしくは-a kotlinでプラグインパッケージで使う言語を指定します。何もつけない場合iOSではObjective−C、AndroidではJavaを使うことになります。

オプションを指定してコマンドを走らせると雛形プロジェクトが立ち上がります。
デフォルト状態のものを見ながらどんなことが書かれているのかを見ていきましょう。

Flutter側の実装

plugin_example/lib/sample

class SoundPlugin {
  static const MethodChannel _channel = MethodChannel('sample');

  static Future<String?> get platformVersion async {
    final String? version = await _channel.invokeMethod('getPlatformVersion');
    return version;
  }
}

プラグイン開発で実装を行うのはこの部分です。
MethodChannel APIをネイティブプラットフォーム側で叩いておりその結果をFlutter側から呼び出しています。
ここではプラットフォームのバージョンを取得しています。

Andriod側の実装

src/main/kotlin/com/example/plugin_example/sample.kt

 class SoundPlugin: FlutterPlugin, MethodCallHandler {
  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private lateinit var channel : MethodChannel

  override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
    channel = MethodChannel(flutterPluginBinding.binaryMessenger, "sample")
    channel.setMethodCallHandler(this)
  }

  override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
    if (call.method == "getPlatformVersion") {
      result.success("Android ${android.os.Build.VERSION.RELEASE}")
    } else {
      result.notImplemented()
    }
  }

  override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
    channel.setMethodCallHandler(null)
  }
}

Flutter側からの呼び出しでMethodChannelのAPIが発火します。
このように呼出しに応じたネイティブ側のプラットフォームAPIを利用して使うことが可能になるわけです。
今回はsampleをそのまま見ました。sampleではMethodChannelを使いましたがこの他にもEeventChannelBasicMessageChannelなどがあります。

まとめ

今回はFlutterのプラグインパッケージを作成する方法とexamlpeにかかれている内容をおさらいしました。
コマンドが用意されており、雛形が作られるので誰でもパッケージが作れるのがいい点ですね。

参考資料

https://docs.flutter.dev/development/packages-and-plugins/developing-packages#plugin
https://api.flutter.dev/flutter/services/MethodChannel-class.html
https://api.flutter.dev/flutter/services/EventChannel/EventChannel.html
https://api.flutter.dev/flutter/services/BasicMessageChannel-class.html

Discussion