LoginSignup
5

More than 3 years have passed since last update.

posted at

updated at

Flutter - Developing Packages & Plugins (日本語訳)

Developing Packages & Plugins の日本語訳

Package introduction

最小のパッケージは以下を含む:

  • pubspec.yaml
  • lib ディレクトリ。ここにコードを置く。最低限 .dart が必要。

パッケージの種類

Dart パッケージ: Dart で書かれたパッケージ。いくつかのものは Flutter 固有の機能を持ち、したがって Flutter フレームワークに依存し Flutter のためにのみ使用できる。例 https://pub.dartlang.org/packages/fluro

プラグインパッケージ: Dart で書かれた特別なパッケージで、Android (using Java or Kotlin) や iOS (using ObjC or Swift) などプラットフォーム固有の実装を含む。例 https://pub.dartlang.org/packages/battery

Developing Dart packages

Step 1: Create the package

Dart パッケージを作るには --template=package フラグとともに flutter create コマンドを実行する:

$ flutter create --template=package hello

以下を含む hello/ ディレクトリが作られる。

  • live/hello.dart: パッケージの Dart コード
  • test/hello_test.dart: パッケージのユニットテスト

Step 2: Implement the package

純粋な Dart パッケージは lib/<package name>.dart に機能を実装するか、lib ディレクトリ以下のいくつかのファイルに実装する。パッケージをテストするために test ディレクトリにユニットテストを追加する。パッケージの構造の詳細については次を参照 Dart library package

Developing plugin packages

もしプラットフォーム固有の機能を呼び出す必要があるならプラグインパッケージを作る必要がある。プラグインパッケージは Dart パッケージ の特別なバージョンで、先の説明にもあったように Android (using Java or Kotlin) や iOS (using ObjC or Swift) などプラットフォーム固有の実装を含む。その API は platform channels を使ってプラットフォーム固有の実装と連携する。 https://flutter.io/platform-channels/

Step 1: Create the package

プラグインパッケージを作るには --template=plugin フラグとともに flutter create コマンドを実行する。--org オプションを使ってあなたの組織を逆ドメイン名表記で指定する。この値は様々なパッケージや自動生成された Android と iOS のコードに含まれる bundle identifiers に使われる。

$ flutter create --org com.example --template=plugin hello

以下のを含む hello/ ディレクトリが作られる:

  • live/hello.dart: プラグインの Dart API
  • android/src/main/java/com/example/​hello/HelloPlugin.java: Android 用のプラグインAPIの実装
  • ios/Classes/HelloPlugin.m: iOS 用のプラグインAPIの実装
  • example/: プラグインに依存するサンプルアプリ

デフォルトではプラグインは Objective-C と Java をそれぞれ iOS、Android のために使用する。必要に応じて -i オプションと -a オプションで Swift や Kotlin を指定することができる:

$ flutter create --template=plugin -i swift -a kotlin hello

Step 2: Implement the package

プラグインパッケージは異なる言語で書かれたプラットフォーム固有のコードをもつが、使いやすくするためにいくつかの固有のステップが必要になる。

Step 2a: プラグインパッケージ API (.dart) を定義

プラグインパッケージの API は Dart コードで定義される。hello/ ディレクトリを開いて lib/helllo.dart を作る。

Step 2b: Android プラットフォームコード (.java/.kt) を追加

Android プラットフォームコードを Android Studio で編集する前にコードを一度ビルドする。(IDE から実行するか、次のようにして cd hello/example; flutter build apk

次に

  • Android Studio を起動
  • Welcome to Android Studio ダイアログで import project を選択、もしくはメニューから File > New > Import Project… を選択し、hello/example/android/build.gradle を選択する
  • Gradle Sync ダイアログで OK を選択
  • Android Gradle Plugin Update ダイアログで Don’t remind me again for this project を選択

Android プラットフォームコードは hello/java/com.example.hello/​HelloPlugin に置かれる。▶︎ボタンを押してアプリを実行することができる。

Step 2c: iOS プラットフォームコード (.h+.m/.swift) を追加

Xcode で iOS プラットフォームコードを編集する前にコードを一度ビルドする(IDE から実行するか、次のようにして cd hello/example; flutter build ios --no-codesign

次に

  • Xcode を起動
  • File > Open を選択し、hello/example/ios/Runner.xcworkspace を選択する

iOS プラットフォームコードはプロジェクトナビゲーター上で Pods/DevelopmentPods/hello/Classes/ に置かれる。▶︎ボタンを押してアプリを実行することができる。

Step 2d: API とプラットフォームコードの接続

最終的に、Dart コードで書かれた API とプラットフォーム固有の実装を接続する必要がある。そのために platform channels を使う https://flutter.io/platform-channels/

ドキュメントの追加

全てのパッケージは以下のドキュメントを持つことが望ましい:

  • README.md - パッケージの説明
  • CHANGELOG.md - それぞれのバージョン毎の変更
  • LICENSE - パッケージのライセンス
  • 全てのパブリックAPI についての API ドキュメント(詳細は以下を参照)

API ドキュメント

プラグインパッケージを公開すると API ドキュメントが自動で生成され、 dartdocs.org に公開される。例 https://pub.dartlang.org/documentation/device_info/0.0.4/index.html

API ドキュメントをローカルマシンで生成したい場合は以下のようにする:
1. パッケージディレクトリに移動
cd ~/dev/mypackage
2. ドキュメンテーションツールに Flutter SDK の場所を伝える
export Flutter_ROOT=~/dev/flutter (macOS or Linux), 
set Flutter_ROOT=~/dev/flutter (Windows)
3. dartdoc を実行(dartdoc は Flutter SDK に含まれる)
$FLUTTER_ROOT/bin/cache/dart-sdk/bin/dartdoc (macOS or Linux)
%FLUTTER_ROOT%\bin\cache\dart-sdk\bin\dartdoc (Windows)

API ドキュメントを書く為の Tips についてはこちらを参照 https://www.dartlang.org/guides/language/effective-dart/documentation

パッケージの公開

パッケージを実装したら、他の開発者が見つけやすいように Pub に公開することができる。
公開する前に pubspec.yaml, README.md, CHANGELOG.md の内容が正しいかレビューする。

次に、dry-run コマンドを実行して全ての analysis をパスすることを確認する:

$ flutter packages pub publish --dry-run

最後に、実際のパブリッシュコマンドを実行する:

$ flutter packages pub publish

パッケージの公開について詳細はこちらを参照 https://www.dartlang.org/tools/pub/publishing

パッケージの依存関係の取り扱い

もし hello というパッケージを作っていて、それが他のパッケージの Dart API に依存している場合、 pubspec.yaml ファイルの dependencies セクションにそのパッケージを追加する必要がある。以下のコードは url_launcher プラグインの Dart API を hello で利用可能にする:

hello/pubspec.yaml

dependencies:
  url_launcher: ^0.4.2

これで import 'package:url_launcher/url_launcher.dart' して launch(someUrl) を実行できるようになる。これは Flutter アプリや Dart プロジェクトでパッケージを含めるのとなんら変わらない。しかし、もし hello が url_launcher が公開しているプラットフォーム固有の処理にアクセスする場合、プラットフォーム固有のビルドファイルに適切な依存関係を追加する必要がある。

Android

hello/android/build.gradle:

android {
    // lines skipped
    dependencies {
        provided rootProject.findProject(":url_launcher")
    }
}

これで import io.flutter.plugins.urllauncher.UrlLauncherPlugin して UrlLauncherPluginhello/android/src 以下のコードからアクセスできる。

iOS

hello/ios/hello.podspec:

Pod::Spec.new do |s|
  # lines skipped
  s.dependency 'url_launcher'

これで #import "UrlLauncherPlugin.h" して UrlLauncherPlugin クラスに hello/ios/Classes 以下のクラスからアクセスできるようになる。

コンフリクトの解消

次のようなケースを想像してください。あなたは some_packageother_package をあなたの hello パッケージで使いたい。そして両方とも url_launcher に依存しているが別のバージョンである。このときコンフリクトが起こりうる。最前の解決策として、依存関係を指定するときに特定のバージョンを指定するのではなく version ranges を指定する。 https://www.dartlang.org/tools/pub/dependencies#version-constraints

dependencies:
  url_launcher: ^0.4.2    # Good, any 0.4.x with x >= 2 will do.
  image_picker: '0.1.1'   # Not so good, only 0.1.1 will do.

もし some_package が上のような依存バージョンを指定していて、 other_package が url_launcher の '0.4.5' や '^0.4.0' を指定していた場合、pub はその依存関係を解決することができる。Grade module や Cocoa pods においても似たような方法をとることができる。

たとえ some_package と other_package が url_launcher について非互換なバージョンを指定していたとしても、互換性のある方法で url_launcher を使うことができる。この場合、コンフリクトは hello の pubspec.yaml に dependency override 追加して特定のバージョンを強制することで対処される。

hello/pubspec.yaml で url_launcher '0.4.3' を強制する:

dependencies:
  some_package:
  other_package:
dependency_overrides:
  url_launcher: '0.4.3'

もしコンフリクトがパッケージ自体によるものではなく、Android の特定のライブラリによるものであった場合、Gradle ビルドロジックに代わりに dependency override を追加する必要がある。

hello/android/build.gradle で guava '23.0' を強制する:

configurations.all {
    resolutionStrategy {
        force 'com.google.guava:guava:23.0-android'
    }
}

Cocoapods は現在 dependency override 機能を提供していない。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
5