Flutter - iOSアプリでライセンスplistを半自動で生成して設定画面に表示できるライブラリを作りました

Swift では @mono0926 さんが作った LicensePlistがありますが、Flutter を使った iOS アプリでは同等のライブラリが存在しなかったので、Dart で作成してみました。

github.com

@mono0926 さんの該当記事はこちら
iOSアプリのライセンス一覧のplistを半自動生成して設定画面にキレイに表示するプログラムをGo言語で作った

今回作成したライブラリの置き場所はこちらです。 今回は iOS のみの対応で Android は対応できてないです。今後対応する予定はありますが、いい感じの実装方法が思い浮かんでないので、誰か助言を...。

github.com

pub.dev

動作結果としては、LicensePlist とほぼ同じになるように寄せました。 (このレイアウトが一番しっくり来てて他のレイアウトがしっくり来なかったので 🥺)

iOS の設定画面から対象アプリを選択すると、「謝辞」セクションが表示されるようになるので、謝辞セクションから下記画面へ遷移することができるようになります。

ライブラリのライセンス一覧 各ライブラリのライセンスページ

使い方 / Usage

dart_license_plist の有効化

dart コマンドを使って dart_license_plist を有効化します。

$ dart pub global activate dart_license_plist
Resolving dependencies...
...
Downloading dart_license_plist <latest_version>...
Building package executables...
Built dart_license_plist:dart_license_plist.
Activated dart_license_plist <latest_version>.

Settings.bundle ファイルの作成

※ すでに Settings.bundle が作成されている場合には、実行不要です。

ライセンス一覧生成前に、iOS では設定画面に謝辞セクションを表示させるために必要な、Settings.bundle ファイルを作成します。このファイルは Xcode から作成する必要があります。

Flutter プロジェクトのiosフォルダにあるRunner.xcworkspaceを開き、ios/Runnerフォルダに Settings.bundle を作成します。

FileNewFile... → Select Settings.bundle

Settings.bundle を作成すると、bundle 内にRoot.plistというファイルが存在しますが、デフォルト状態だとテンプレートが記入されているので、以下のように書き換えておきます。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>StringsTable</key>
    <string>Root</string>
    <key>PreferenceSpecifiers</key>
    <array>
    </array>
  </dict>
</plist>

ライセンス Plist の生成

dart_license_plistは Flutter プロジェクトのプロジェクト直下で実行します。 このコマンドを実行すると、上記で生成したSettings.bundle内にファイルを生成したりします。

設定画面に「謝辞」セクションを表示するために、Root.plistを編集する処理も含まれています。

$ dart pub global run dart_license_plist

実行するとプロジェクト直下にあるpubspec.lockを元に使用しているライブラリを取得して、ライセンスデータを取得しに行きます。 Generate Finishedが表示されたら plist 生成の完了です。

取得に失敗したパッケージに関しては、最後にエラーとしてパッケージ名が一覧で表示されます。

[INFO] Fetching _fe_analyzer_shared data... (URL: https://pub.dev/packages/_fe_analyzer_shared)
[INFO] _fe_analyzer_shared's license url: https://pub.dev/packages/_fe_analyzer_shared/license
...
[INFO] Generating xdg_directories.plist...
[INFO] Generating xml.plist...
[INFO] Generating yaml.plist...
[INFO] Generate Finished.

実行後のSettings.bundle内の構成は以下のようになっているかと思います。

Settings.bundle
├── Root.plist
├── dev.nomunomu0504.dart_license_plist
│   ├── flutter.plist
│   ├── dio.plist
│   └── ...
└── dev.nomunomu0504.dart_license_plist.plist

Flutter アプリを再 Build して端末にインストールすると、設定画面から謝辞およびライセンスを確認することができます。

実行時のオプション

実行時のオプションとして指定できるのは、以下の項目になります。

option value description
--version, -v - dart_license_plist の version を確認できます。
最新バージョンが存在した場合には、update を行うこともできます。
--verbose - デフォルトは INFO, ERROR のログのみですが、
verbose オプションを使うことで、DEBUG ログも表示できるようになります。
--custom-license-yaml=value yaml path (string) plist 生成時の設定および、カスタムライセンスの設定等を記述した yaml ファイルのパスを指定できます。

--custom-license-yaml オプション

custom-license-yaml で設定できる項目として、現状ではライセンス一覧に表示しないパッケージを指定できるexcludeと、カスタムライブラリを設定できるpackagesの2つになります。

yaml ファイルのテンプレートはこんな感じになります。

exclude:
  <fetch_exclude_package_name>:
  <fetch_exclude_package_name>:
  <fetch_exclude_package_name>:
  ...

packages:
  <custom_license_package_name>:
    license: |
      <custom_license_text>

  <custom_license_package_name>:
    license: |
      <custom_license_text>

  <custom_license_package_name>:
    license: |
      <custom_license_text>

設定ファイルが読み込まれている場合、コマンド実行時に読み込んでいるデータが表示されます。

$ dart pub global run dart_license_plist --custom-license-yaml=.custom_license.yaml
[INFO] -----
[INFO] Exclude package name list            ★★ excludeで設定されているパッケージ名一覧
[INFO] flutter_test
flutter_web_plugins
[INFO] -----
[INFO] Custom license package name list     ★★ pakcagesで設定されているカスタムライブラリ一覧
[INFO] flutter
[INFO] -----
[INFO] Fetching _fe_analyzer_shared data... (URL: https://pub.dev/packages/_fe_analyzer_shared)
...

exclude と packages に同じパッケージが設定されていると、エラーが表示されますので確認して修正してください。

exclude

exclude には、ライセンスデータのフェッチをスキップするパッケージ名を指定します。

exclude:
  flutter:
  flutter_web_plugins:

設定されているパッケージのライセンスデータを取得する際に、スキップされるようになります。

[INFO] flutter_test is setting exclude. Fetch Skipping...
[INFO] flutter_web_plugins is setting exclude. Fetch Skipping...

packages

packages では、パッケージとして使っていないがライセンスとして載せたい場合に設定すれば、ライセンス一覧に表示できるようになります。 flutter は pub.dev にライセンス情報はなく、Github のライセンスを掲載する必要があります。 ※ 本当はここらへんも自動でできるようになればいいんですが、実装できていません 🙇‍♂

ここで設定されているライセンス情報は、pub.dev とかから取得したライセンス情報よりも優先して利用されます。

packages:
  flutter:
    license: |
      Copyright 2014 The Flutter Authors. All rights reserved.

      Redistribution and use in source and binary forms, with or without modification,
      are permitted provided that the following conditions are met:

          * Redistributions of source code must retain the above copyright
            notice, this list of conditions and the following disclaimer.
          * Redistributions in binary form must reproduce the above
            copyright notice, this list of conditions and the following
            disclaimer in the documentation and/or other materials provided
            with the distribution.
          * Neither the name of Google Inc. nor the names of its
            contributors may be used to endorse or promote products derived
            from this software without specific prior written permission.

      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
      ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
      WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
      DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
      ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
      ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
      SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.