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/Development
、 Pods/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 ドキュメントをローカルマシンで生成したい場合は以下のようにする:
- パッケージディレクトリに移動 cd ~/dev/mypackage
- ドキュメンテーションツールに Flutter SDK の場所を伝える
export Flutter_ROOT=~/dev/flutter
(macOS or Linux),set Flutter_ROOT=~/dev/flutter
(Windows) - 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
して UrlLauncherPlugin
に hello/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_package
と other_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 機能を提供していない。