見出し画像

Javaで作ったアプリをFlutterに移植してみた

こんにちは、20年ものプログラマーです。

他の投稿にも書いたのですが、以前ブラジルで就職活動をするにあたり、何か売りになるものをと思いJavaで開発したAndroidアプリ「Papagaio Japonês(ポルトガル語で"日本語のオウム"という意味)」を、今年になってFlutterに移植してリリースしてみました。

外国人に日本語を覚えてもらうアプリで、テキスト読み上げで日本語の単語を読み上げた後、聞こえた通りにユーザに発音してもらい、音声認識して同じ単語が言えていたら正解、という機能です。聞いた事をオウム返しにしゃべるので、アプリ名に「オウム」と入れました。

ずっとダウンロード件数が伸びなかったそのアプリが、2年ぶりに何件かダウンロードされていたですが、実はこのアプリ、Androidのパーミッション周りの仕様が変わった時に、「誰も使ってないし、いいや」と思って対応してなくて、音声認識の機能が動いていなかったのでした。

放置していたアプリの出来の悪さが急に恥ずかしくなり、せっかくダウンロードしてくれる人がいるんだから、ちゃんと動くように作り替えよう、どうせならFlutterを駆使して、キレイで使いやすい画面にしちゃおう、と思いました。

しかも、前回はポルトガル語圏のみでリリースしていたのですが、今回は多言語対応をして全世界リリース。+IOS版✖全世界という事でダウンロード数は前より伸びるかも。かつ広告も、細長いバナーだけでなく全画面広告も入れてみました。やっぱり広告収入欲しいですよね~。あわよくば(笑)

Flutterのイイところ

一作目アプリの時は、全てJavaで作ったのですが、キレイなレイアウトにするのがとても難しくて、何だかカッコ悪いレイアウトになってしまっていました。リスト画面を実装するのも難しかったし、少し余白サイズを変えたり線の太さを変えたりなど、簡単な事でもけっこう難しかったです。

Flutterだと、あまり深く考えずに部品を並べていって、「もう少し余白が広い方がいいな~」とか「文字を中央揃えにしようかな~」などとプロパティをちょいちょい変えながら実装を進めていくと、自然とキレイな画面に仕上がっていきます。

EC2 Macインスタンスの再利用

前のアプリのIOS版をリリースした時に使った、AWSのEC2 Macインスタンスのスナップショットを取っておきました。AWSではこのスナップショットを置いておくだけで月々2ドルぐらい掛かりますが、もう一度ゼロから同じ環境を作る事を考えたら、取っておいた方が断然おトクです。

Mac環境に開発環境を作る時、ダウンロード速度は遅いし、プルダウンメニューの一つ下の要素を選ぶだけで30秒ぐらい待たされるし、とにかく動作が遅い。(ブラジルからアメリカのリージョンに接続してるので、多分日本で東京リージョンに接続していればもっと速いだろうと思いますが)

スナップショットからAMIという起動イメージを作って、あらかじめ割り当てておいた専有ホストを指定してインスタンスを起動すると、あらステキ!前の環境がちゃんと残ってました。ソフト類も、Gitでチェックアウトしたソースも、SSL接続の設定も残っていましたが、PATHだけ通し直しました。

Android版はそこそこラクだった

Flutterのtext_to_speechというパッケージと、voice_recognitionというパッケージを使って、Java版の時とだいたい同じ機能がわりとすぐ実装できました。余裕こいて、Google Translation APIを使った新しい機能も追加しました。

Mac版はなんか大変

前回のMac作業では、Linuxコマンドが分からなくて苦労したり、SSLの設定やらフォルダの場所やら基本的な事が分からず時間が掛かったのですが、今回は別な事でハマりました。

Xcodeでビルドする時、謎の「パッケージが見つかりません」エラーが頻発するのでした。いや、ちゃんとあるはずなのに。何言ってるのかさっぱりわからん・・・。CocoaPodsというライブラリ管理ツールのエラーなのですが。こういうのって便利だけど、動かない時はすごくシンドイですね。

ググると、Podfileという物を書き換えろとか一時フォルダを消せとか、flutter cleanした後に pod install しろとか、対応バージョンの数字を上げろとか、同じ問題に関する記事はたくさん見つかり、全部やってみましたがぜんぜん解決できませんでした。

Android StudioもFlutterも両方Google製だから、使いやすいように考えて作られてますね。XcodeとFlutterは、途中までターミナルからflutterコマンドを使って、途中からXcodeの画面でボタンを押して・・・と、相性が悪いっていうか。どこまでがどっちの責任なのかがわかりにくい感じ。

解決した方法は、ターミナルで flutter build ipa と打つ事でした。このやり方で、Xcodeに頼らずflutterコマンドのみでリリースビルドを作ってくれました。上記の問題はflutterとXcodeの連携がどこかでうまく行っていないためのものなのでしょう。

しかし、この方法でビルドした場合、IOSシミュレーターで動かす事ができませんでした。ググると、シミュレーターで動かすにはXcodeの機能でビルドしなければならず、コマンドで作ったビルドを実行する事はできないという記事が見つかりました。

いったんTest Flightリリース。そこで新たな問題

XcodeのIOSシミュレーターって、マイクやカメラの機能が使えません。なので、Test Flight(Apple Storeのテスト版)にリリースをして、自分のテスト用の実機にダウンロードしてみて初めて、テキスト読み上げや音声認識の機能がうまく動かない事が分かりました。

text_to_speechで文字を読み上げた後にvoice_recognitionで音声認識をして、もう一度text_to_speechの読み上げをすると、音声が出なくなるという問題です。これは、一番大事なところなので、何とかしないとアプリの意味を成しません。

しかし、このMac環境を一度起動させると2400円ぐらい掛かるので、上記のようなコーディングの問題で時間をかけるのはもったいない。何かMac上でしかできない事を・・・。IOSシミュレーターを動かして、Apple Storeに掲載するための画面キャプチャを撮っておこう!と思いました。

その後、リリース可能時間ギリギリまで、Xcode側のビルドエラーを解消するためにググったり試してみたり、いろいろな解決策を施行錯誤し続けたのですが、結局解決できませんでした。Androidで撮ったキャプチャを切り貼りしてApple Store用のをそれっぽく作る事にしよう・・・。

そしてMac環境を終了させた後、パッケージの組み合わせ問題を試行錯誤しながらCodeMagicでビルド→Test Flightリリース→実機テストを繰り返し。いろいろ試してみて、相性のいいパッケージの組み合わせを見つけました。flutter_ttsとspeech_to_textで、両方の機能が使えるようになりました。

ちなみに作ったアプリはこちらです!

Parrot Japanese

Parrot Japanese IOSバージョン
IOS版
Parrot Japanese Androidバージョン
Android版

読んでいただき、ありがとうございました。

よろしければサポートお願いします!通貨レートの低い海外に暮らしているので、ときどき日本の電子書籍を購入するのに使いたいと思います!