本シリーズ(?)の最初の投稿で書いたことですが、私がFlutterの学習を始めた初期の目的は自分が開発したバックエンドと連携するフロントエンド(Webアプリ)を実装することでした。
しかし、ある程度Flutterで動くものが作れるようになってくると本命のスマホアプリを実装してみたくなります。
Flutterの最大の特徴はAndroid、iOS、Web、macOSなど異なるOSで動作するアプリを同一ソースから生成できるというクロスプラットフォーム性にありますが、その恩恵を最も受けられるケースとして想定されるのは、やはりスマホ(Android、iOS)アプリの開発といって良いでしょう。
Flutterに関するネットの記事を見ても、ほとんどがスマホでの動作を前提とするもので、Webアプリとして実装するケースなどほとんど見た記憶がありません。
また、今後はスマホのカメラ機能や録音機能などとも連携するようなアプリも開発したいと思っていますが、ハードの能力を十分に使いたいと思った場合、Webアプリでは色々と制約がありそうで心もとないです。
と言うことで、今後は「スマホアプリとしての実装を前提とした開発(学習)」に目的を切り替えていきたいと思います。
ただし、バックエンドが提供するAPIを利用して目的とするサービスを提供するというフロントエンド的な位置付けである点は今後も変わらないものとします。
では、最初の一歩として、今まで作ってきたソースをスマホアプリとして動作させてみたいと思います。
エミュレーター・シミュレーター
スマホアプリとして生成した実行形式をどこで動かすかですが、開発段階においては対象デバイスを直接的に使用せずに、エミュレーター・シミュレーターのような擬似・代替環境を用いることが良くあります。
Flutterの開発環境でもスマホ用のエミュレーター・シミュレーターを使った動作確認が可能です。
Androidエミュレーター
Androidに関しては「Android Studio」をインストールすることでエミュレーターを使用することができるようになります。
Androidのバージョンも色々と選べるようですが、今回はあくまで自製アプリを動かしてみられれば良いだけなので適当に選択することにします(Pixel 6 API 33)。
また、エミュレーターには「cold boot」とそうでないもの(fast boot)の2種類があり、「cold boot」はエミュレーターを完全にシャットダウンした状態から起動するようです。一方「fast boot」の方は一時停止状態から起動するため、文字通り起動に要する時間が短縮できるようです(ノートPCのハイバネーションのようなものでしょうか)。
とりあえず「fast boot」版を指定すれば数秒〜数十秒程度でエミュレーターが使用できるようになります。
エミュレーター上でのアプリの動作も、若干重いですがストレスが溜まるほどではないとの印象です。
ただ、Androidエミュレーターの最大の弱点はドメインの名前解決が簡単にできない点があります。
今まではMac上でWebアプリまたはMacアプリとして試用してきましたが、この運用方法においては接続先バックエンド(動作検証用に社内LANからのみアクセス可能)のドメインに関する名前解決にはhostsファイル(/private/etc/hosts)を使用していました。
しかし、Androidエミュレーターでは前述のファイルの設定内容は有効ではないようです。
そもそもエミュレーターとは「特定のハードウェアやソフトウェア環境を別のプラットフォームで動作させるもの」であり、ホストOS(Mac)の設定がゲストOS(Android)で有効になることを期待する方が無茶なのかもしれません。
また、Android自体にもhostsが存在し、ネット情報では必要な設定を同ファイルに追加できるような記事もあったりしたのですが、個人的にはパーミッション等の問題で成功していません。
そんなこんなで最終的に辿り着いた現時点での唯一の解決策は、ブロードバンドルータのDNS機能で名前解決を行わせる方法でした。
AndroidのLAN(Wifi)情報を信じれば、Android自体は社内LANに直接アクセスしている訳ではなさそうです。割り振られたIP(10.0.2.xx)のネットワーク部がLANのIP(192.168.12.xx)とは異なっていますので。また、最寄りのDNSサーバも10.0.2.3となっています。
しかし、エミュレーター上からインターネット上のサイトにもアクセスできますので、社内LAN経由で外部との通信ができており、正規のDNSを使用しての名前解決も可能にはなっているようです。この辺はエミュレーターが頑張っているのでしょう。
社内LANにおける最寄りのDNSサーバはブロードバンドルータになっていますが、弊社使用のブロードバンドルータでは名前解決に関する情報(a、ptrレコード)の設定が可能であるため、ここに紐付けたいドメインとIPのセットを設定することで社内LAN内での当該ドメインに関する名前解決が可能になります。
エミュレーター上のアプリにおける名前解決でも上記ブロードバンドルータの設定内容が有効です(DNSの原理を詳細に理解している訳ではないので、具体的な仕組みにまでは言及できませんが)。
iOSシミュレーター
iOSに関しては「Xcode」をインストールすることでシミュレーターを使用することができるようになります。
iOSのバージョンに関しては、少なくとも私の環境で使用できるものは「iPhone 14 Pro Max」のようです(ちょい古めです)。選択肢があるかどうかは不明です。
こちらは「シミュレーター」であるためかAndroidエミュレータと異なりMacのhostsファイルの設定内容がそのまま有効であり、ドメインの名前解決が簡単です(ただ、前述したブロードバンドルータでの名前解決により本アドバンテージはあまり意味がなくなりますが)。
iOSシミュレーターの最大の弱点は動作はかなり重い点です。
まずシミュレーターの起動に4分近くかかります。
Androidエミュレーター(fast boot)は数十秒で起動しますので、それと比較するとかなり待たされる印象です。
エミュレーターが対象OSの動作環境を丸ごと構築するものだとすると、シミュレーターはあくまで対象OSのように見える擬似環境を構築するだけなので、シミュレーターの方が早く起動できても良いと思うのですが。
また、対象アプリの操作性もAndroidエミュレーターと比較してさらに重たいです。
一覧のスクロールなどは実際の操作から少し遅れてぎしぎしと動く感じです。
まぁ、我慢すれば使えるレベルではありますが。
実機
エミュレーター・シミュレーターのような擬似・代替環境ではなく、スマホ実機上でも開発段階のアプリを動かすことが可能です。
ただし、スマホ側で特殊な設定が必要なので、ここではその方法に触れたいと思います。
なお、残念ながら実機としては個人的にはAndroid端末しか所有していないので、今回紹介できるはAndroid限定の方法になります。
また、Androidのバージョンや機種によって操作方法が異なる可能性がありますので、その点はあらかじめご了承ください。
まず、実機側で「開発者向けオプション」なるものを有効にする必要があります。
ただし、同オプション有効化により端末上で通常では不可能な操作ができるようになるため、操作に問題があると実機が正しく機能しなくなる可能性があるようです。
よって、本オプションを使用する場合は現役で使用中の端末ではなく、退役済みの端末を使用する方が無難です(このようなケースを考慮して、個人的には新しい端末購入時に古い端末も保持しておくようにしています)。
具体的な設定方法は以下の通りです。
- 「設定」から「デバイス情報」画面を開き、「ビルド番号」を7回連続でタップします。
「開発者向けオプションが有効になりました」というメッセージが出ればOKです。 - 「設定」から「システム」を開くと「開発者向けオプション」というメニューが増えているので、これをタップします。
「USBデバッグ」という項目があるので、これをONにします。
確認画面が出るかと思いますが、「OK」をタップします。
上記により実機とUSBで接続したPC側とでデータのやり取りなどができるようになります。
実際にUSBケーブルで実機とMacを繋げて、以下のようにコマンド実行してみます。
# flutter devices
3 connected devices:
SH 51A (mobile) • 35***********42 • android-arm64 • Android 12 (API 31)
macOS (desktop) • macos • darwin-x64 • macOS **** ****** darwin-x64
Chrome (web) • chrome • web-javascript • Google Chrome ************
No wireless devices were found.
Macアプリとして動作させる環境(macOS)やWebアプリとして動作させる環境(Chrome)と並んでAndroidが利用可能な環境として認識されています。
この状態でPC(Mac)側で開発中のアプリの起動を行うと、実機側でアプリが動きます(具体的な起動操作は後述)。
蛇足ながら、LAN内バックエンドにアクセスするために、ネットワーク設定としては4G, 5Gのようなモバイル通信の使用を解除し、Wifiで社内LANに接続するようにしておく必要もあります(退役機であればSIMが外されているはずなので、Wifiしか通信の選択肢がなくなっていると思いますが)。
なお、このケースにおいても名前解決の方法が課題になりますが、先に示したブロードバンドルータでの名前解決が有効になっていれば問題ありません。
また、パフォーマンスに関してはエミュレーター・シミュレーター使用時とは異なり普通に動きます。
逆に言えばエミュレーター・シミュレーターでは相応に無理をしているということなのでしょう。
動作確認
上記で紹介した各環境で実際に開発中のアプリを動かす方法に関しては以下のようになります。
コマンドラインでの起動もできますが、VSCodeを使用して開発を行なっている場合はVSCode上でも起動操作ができます。
こちらの方が簡単なので、こちらで試してみたいと思います。
まず、画面右下に現在選択されているdeviceが表示されているかと思います。
私の環境ではChromeがデフォルトになっているようです。
上記箇所をクリックすると画面上部中央に利用可能なdevice一覧が表示されます。
エミュレーター・シミュレーターに関しては、ここで選択することで同環境を起動しつつ同環境がアプリ実行環境として選択された状態になります。
実機に関しては既に起動+USBケーブルで接続された(つまりは環境の準備は済んでいる)状態なので実行環境として選択のみです。
実行環境選択後にVSCode上でアプリの実行操作を行うと、選択された環境上でアプリが起動されます。
アプリの実行方法はいくつかありますが、メニュー上の「実行」から「デバッグの開始」もしくは「デバッグなしで実行」をクリックする方法がわかりやすいかと思います。
まとめ
とりあえず、Flutterで開発したソースをスマホアプリとして動作させることができるようにはなりました。
ただ、現状の機能は画面への表示やテキストレベルの入力程度であるため、スマホアプリ化の恩恵はほとんどありません(Webアプリ開発が前提だったので当然ではありますが)。
次回投稿ではカメラ機能の実装辺りを狙ってみたいと思います。