🐈

【Flutter】アプリID(iOS:Bundle ID、Android:Application ID)を変更するシェル

2024/06/17に公開

はじめに

けっこうな昔に作ったシェルがありチームで使っているのですが、
特別秘密にする話でもないので公開します、という記事です!

アプリIDを変更するパッケージの存在を最近知りまして、別手段くらいに捉えていただけますと幸いです。
(シェルをちまちま作っていたときは知らなかったです!)

アプリIDを変更するパッケージ
https://pub.dev/packages/change_app_package_name

優位性は、「シェルの方が、(わかる人には)微調整とかできるよね」くらいです。
やってることは変わらそうなので悪しからず。

私が微調整している部分について最後に記載します。

対象者

Flutterで一度作ったプロジェクトの
アプリID(iOS:Bundle ID、Android:Application ID)を変更したい方

前提知識として「アプリID(iOS:Bundle ID、Android:Application ID)」が何かは知っている(※ この記事では説明しない部分)。

パージョン情報

動作確認した環境について記載

  • OS : Mac
    • Windowsだと微調整が必要かもです。
  • Flutterのバージョン 直近だと3.22.1で動作確認済み
    • ※ 古いバージョンでも基本は動くはずです。

書いていること・書いていないこと

書いていること

  • 実際のシェル
  • 利用方法
  • 利用時の注意点

書いていないこと

  • シェルの事細かな説明

実際のシェル(ベース)

#!/bin/sh

if [ $# != 1 ]; then
    echo 引数エラー、パッケージ名を引数で渡してください: $*
    exit 1
else
    echo パッケージ名(bundle Id Application ID)を「$1」に変更
    #「package="(初期パッケージ)"」を「package="(引数)"」で置換
    sed -i "" -E s/package=\".*\"/package=\"$1\"/g ./android/app/src/main/AndroidManifest.xml
    sed -i "" -E s/package=\".*\"/package=\"$1\"/g ./android/app/src/debug/AndroidManifest.xml
    sed -i "" -E s/package=\".*\"/package=\"$1\"/g ./android/app/src/profile/AndroidManifest.xml
    echo AndroidManifest.xmlの変更完了
    # 「applicationId "(初期パッケージ)"」を「applicationId "(引数)"」で置換
    sed -i "" -E s/applicationId" \".*\""/applicationId" \"$1\""/g ./android/app/build.gradle 
    # 「namespace "(初期パッケージ)"」を「namespace "(引数)"」で置換
    sed -i "" -E s/namespace" \".*\""/namespace" \"$1\""/g ./android/app/build.gradle 
    echo build.gradleの変更完了
    # MainActivityのpackage名を変更
    # MainActivityの場所は初期のパッケージ名で変わるのでfindコマンドで取得する
    KTPATH=`find . -name MainActivity.kt`
    sed -i "" -E s/package" .*"/package" $1"/g $KTPATH
    echo MainActivity.ktの変更完了
    # フォルダ名の作成用に「.」を「/」に変換
    DIR=`echo $1 | sed -e "s/\./\//g"`
    # 新しいパッケージ名でフォルダ作成
    mkdir -p ./android/app/src/main/kotlin/$DIR
    # ファイルの移動
    mv $KTPATH ./android/app/src/main/kotlin/$DIR
    # 以前のフォルダを削除
    rm -r $(echo $KTPATH | grep -o ./android/app/src/main/kotlin/'[^/]*/')
    echo フォルダ変更完了
    # iOSのバンドルIDの変更
    # Xcodeで変更する場合も、変更箇所は一箇所だけ
    sed -i "" -E s/PRODUCT_BUNDLE_IDENTIFIER" = .*"/PRODUCT_BUNDLE_IDENTIFIER" = $1;"/g ./ios/Runner.xcodeproj/project.pbxproj
    echo バンドルID変更完了
fi

メモ
build.gradlenamespaceについてはFlutter3.7系ではなく、Flutter3.10系くらいから増えた記述のようです。(片っ端からプロジェクトをcreateして確認した限り)

Android Gradle Plugin 7.3 以上くらいからの話のよう
https://bps-tomoya.hateblo.jp/entry/2022/05/11/193325

利用方法

実行場所
・プロジェクト直下

シェルに実行権限を渡す。

$ chmod 755 change_package_name.sh

パッケージ名を引数として渡して実行
例)「jp.test.app」の場合

$ ./change_package_name.sh jp.test.app

利用時の注意点

一つバグ的なものがあって、運用で回避してます。
(シェルで回避する術はあると思うが、そこまで頑張らなかったというのが近い)

問題箇所)
Android側で「新しいアプリIDでフォルダ作成」と「過去のフォルダ削除」部分

発生するパターン)
jp.co.xxx.appjp.co.yyy.appなど
変更前と、変更後でアプリIDに重なる部分がある場合。

回避方法)
一度、「全く重なる部分がないアプリID」にして変更する。
例)

$ ./change_package_name.sh xxx.yyyy.zzz
$ ./change_package_name.sh com.example.app

実際の使っているシェル(微調整版)

ここは個人的な話ですが、
環境分けを以下の記事を参考にやっていまして

https://zenn.dev/altiveinc/articles/separating-environments-in-flutter-old-edition

iOSのバンドルIDの部分だけ、flavorが反映されるようにシェルの中で記載いじってます。

該当箇所のリンクと同じになるように

    # iOSのバンドルIDの変更
    # Xcodeで変更する場合も、変更箇所は一箇所だけ
    sed -i "" -E s/PRODUCT_BUNDLE_IDENTIFIER" = .*"/PRODUCT_BUNDLE_IDENTIFIER" = $1;"/g ./ios/Runner.xcodeproj/project.pbxproj

    # iOSのバンドルIDの変更
    # Xcodeで変更する場合も、変更箇所は一箇所だけ
    sed -i "" -E s/PRODUCT_BUNDLE_IDENTIFIER" = .*"/PRODUCT_BUNDLE_IDENTIFIER" = \"$1\$(APP_ID_SUFFIX)\";"/g ./ios/Runner.xcodeproj/project.pbxproj

に変更している形(APP_ID_SUFFIXを入れてしまっている)です。

上記変更に対する余談
「アプリIDを変える」ことと「環境分け」は全く目的の違う対応なので、
私のように混ぜるかどうかは個々の判断でお願いします!

個人的には使い勝手はいいです。
ただプログラミングでいう「責務の分離」的には間違っているようにも思ってます。

以上です!

Discussion