Flutter製のアプリ自体は少しずつストアでも見られるようになってきていると思うけど、
既存のネイティブアプリからのリプレイスって話は見かけてないのでやったこと、苦労した点をまとめました。
Flutterそのもので苦労した話は気が向いたら別に書きます。
パッケージ名を合わせる
当然だけどリプレイスなので既存アプリとパッケージ名を合わせる必要がある。
解決方法
こちらを参考にしたらすぐ出来た。
平たく言えば普通にAndroidアプリのパッケージ名を変更するのと同じことをするだけ。
ビルドの署名を合わせる
これも合わせないとストアに登録出来ないのでやる。
ちなみに新規なら公式ドキュメントの通りやれば良い。
解決方法
ぶっちゃけ新規の手順でキーストアの作成の代わりに既存のファイルを使うだけだけど一応記載しておく。
既存アプリのキーストアファイルをandroid/app配下に置く
android/key.propertiesファイルを作成
storePassword=<既存のストアパスワード>
keyPassword=<既存のキーパスワード>
keyAlias=<既存のキーエイリアス>
storeFile=<キーストアファイル名>
build.gradleを編集
以下の2箇所を編集
// 以下3行を追加
def keystorePropertiesFile = rootProject.file("key.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android {
// buildTypes {
// release {
// // TODO: Add your own signing config for the release build.
// // Signing with the debug keys for now, so `flutter run --release` works.
// signingConfig signingConfigs.debug
// }
//}
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
データのマイグレーション
既存のアプリにログイン機能があり、内部にトークンなどを保持していたため、
それを引き継がずに更新すると情報が全て消えてしまうことが判明した。
幸い、SharedPreferencesで保持していたのでSharedPreferencesプラグインを使えば
そのまま引き継げるかと思ったけど話はそう簡単ではなかった。
まずFlutterのプラグインではインスタンスの名前が選べずデフォルト一択だった。
Androidではインスタンスを取得する際に名前をつけられるので、ここでいきなり躓いた。
更にプリファレンスの名前にprefixを自動でつける非常に余計親切な仕様があった。
なので例えばaccessTokenみたいなプリファレンスを参照すると実際には
flutter.accessTokenを参照することになる。
解決方法
どうしようもないので自前でSharedPrefrencesのプラグインを実装した。
と、しれっと書いたけどこれだけで調査も含めて諸々1週間位かかった。
※なお、realmも使っていたが読み込んだデータのキャッシュ程度にしか使ってなかったので
今回は引き継がなかった。
iOSとのバージョンの棲み分け
Android/iOS両方ともネイティブアプリをリリースしているが、歴史的な経緯があってバージョンが全然違う。
合わせようとするとかなりメジャーバージョンがぶっ飛ぶことになるので、それぞれでバージョンを指定することにした。
解決方法
app/build.gradleのL14辺りでバージョンコードとバージョンネームを設定しているのでそこを書き換える。
もちろんこの対応でFlutter側からも問題なくAndroid/iOSそれぞれのアプリバージョンを取ってこられる。
//def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
//if (flutterVersionCode == null) {
// flutterVersionCode = '1'
//}
def flutterVersionCode = '100' // ←よしなに
//def flutterVersionName = localProperties.getProperty('flutter.versionName')
//if (flutterVersionName == null) {
// flutterVersionName = '1.0'
//}
def flutterVersionName = '2.0.0' // ←よしなに
まとめ
普通に作る分にはFlutterはかなり便利だと思うけど、こういうレアケースに手を出すとちょっと面倒なこともあるよということで、
同じようなことを考えている、あるいはこれからやっていかなくちゃあいけない人たちの参考になれば幸いです。