子供のお勉強用にちょっとしたネイティブアプリを作りたくなり、 Flutter で作ってみることにしました。
本記事は、公式の Get Started を見ながら、Android/iOS/Web のクロスプラットフォーム動作環境を構築して、サンプルアプリを軽く動かしてみるところまでの内容となっています。

Flutterの特徴

  • 1つのコードベースで、クロスプラットフォーム(Android/MacOS/Windows/Linux/iOS/Web)で動作するアプリを作れる
    • => 開発・運用・学習コストが小さい
  • Google がリードする OSS
    • => 開発が頻繁
  • 独自のレンダリングエンジンを使っている
    • => swiftやkotlinを使ったネイティブ開発より低速
  • 一般的な端末固有機能は対応している
    • => 全部対応してる訳ではなく、最新機能への対応も少し遅れる
  • widget を組み合わせてUIを作る
    • => flutter独自のUIコンポーネントが豊富
  • Dart(javaに似た言語)で記述する
    • => あまり流行ってない
  • Adobe XD からコードをジェネレートできる
    • => 開発効率が高い

Requirement

  • OS: macOS (64-bit)
  • Disk Space: 2.8 GB
  • ツール: git

Flutter SDKのインストール

  1. ダウンロード
    • こちらから最新のリリースバンドルをダウンロードする
      (本記事では2.0.4-stableを利用)
  2. 解凍
    • 好きなフォルダに解凍する(本記事では~/tools/に解凍)
  3. Flutter へのPATHを追加
    • ~/.bash_profile~/.bashrcにてPATHを設定します
      vi ~/.bash_profile
      + export PATH=$PATH:~/tools/flutter/bin
      source ~/.bash_profile
      which flutter
      > /Users/xxx/tools/flutter/bin/flutter

サンプルプロジェクトを作成・実行

ここまでで、すでにWebアプリとして Flutter アプリを動かす環境ができていますので、サンプルアプリを動かしてみたいと思います。

  1. 以下のコマンドを実行すると、Flutter プロジェクトが作成される
    flutter create flutter_sample
  2. スターターアプリが内包されているので、アプリを実行する
    cd flutter_sample
    flutter run
  3. Chrome でWeb画面が表示される

「+」ボタンをクリックすると、カウンターがカウントアップされていきます。
ここまでは非常に順調ですね。

必要なソフトを診断

次は、その他必要なソフトをインストール/設定していきます。
flutter doctorコマンドで足りてないものを確認できます。

flutter doctor

> [✓] Flutter (Channel stable, 2.0.4, on Mac OS X 10.14.6 18G8022 darwin-x64, locale ja-JP)
> [✗] Android toolchain - develop for Android devices
>     ✗ Unable to locate Android SDK.
>       Install Android Studio from: https://developer.android.com/studio/index.html
>       On first launch it will assist you in installing the Android SDK components.
>       (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
>       If the Android SDK has been installed to a custom location, please use
>       `flutter config --android-sdk` to update to that location.
>
> [✗] Xcode - develop for iOS and macOS
>     ✗ Xcode installation is incomplete; a full installation is necessary for iOS development.
>       Download at: https://developer.apple.com/xcode/download/
>       Or install Xcode via the App Store.
>       Once installed, run:
>         sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
>         sudo xcodebuild -runFirstLaunch
>     ✗ CocoaPods not installed.
>         CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the Dart side.
>         Without CocoaPods, plugins will not work on iOS or macOS.
>         For more info, see https://flutter.dev/platform-plugins
>       To install see https://guides.cocoapods.org/using/getting-started.html#installation for instructions.
> [✓] Chrome - develop for the web
> [!] Android Studio (not installed)
> [✓] VS Code (version 1.54.3)
> [✓] Connected device (1 available)
>
> ! Doctor found issues in 3 categories.

Android toolchainXcodeAndroid Studioのインストールが必要なようです。
次項ではまず Android に関する設定を行います。

Android 向けの設定

Android Studio インストール

Google が提供する Android プラットフォーム向けアプリケーションソフトウェア開発用のIDEである Android Studio をインストールします。

  1. こちらからダウンロードしてインストールする
  2. Android Studio を起動して、セットアップウィザードを実行する
  3. 先ほどサンプルプロジェクトを作ったので、Open an Exixting Projectでサンプルプロジェクトを開く
  4. プラグインをインストールしておく
    • Preferences... > Pluginsから Dart と Flutter プラグインをインストールする
      • Dartは.dartファイルを開くと勝手に suggest してくれるのでそのタイミングでもOK
      • Flutter プラグインは、エミュレータでのデバック実行などで必要
  5. Android SDK のライセンスに同意しておく
    flutter doctor --android-licenses

Android エミュレータの設定

動作確認のために、以下を参考に Android エミュレータを設定します。
https://developer.android.com/studio/run/emulator-acceleration

  1. Android Struio 右上の方に表示されているAVD Managerアイコンをクリック
  2. 仮想デバイスのリストが表示される
    • Google Pixcel 3a が最初から登録されている
    • + Create Virtual Device... から新しく仮想デバイスを登録できるが、ここでは割愛
  3. ▶︎ ボタンでデバイスを起動する
    • 初回AVD Manager Unable to locate abcというエラーが出た場合は、メニュー > Project Structureで、SDKを設定することで解決できる
    • ちゃんと起動すると以下ように仮想的なスマホ画面が表示される
  4. 最後に、サンプルプロジェクトをエミュレータで表示する
    • 画面上部のFlutter Device Selectionプルダウンで、対象のデバイスを選択する
    • 選択するとエミュレータ画面が立ち上がる
      • もしFailed to install the following Android SDK packages as some licences have not been accepted.というエラーが出る場合は、flutter doctor --android-licensesを実行する
    • ▶︎ボタンでmain.dartを実行すると、エミュレータ画面に対象のアプリケーションが描画される

      「+」をクリックするとちゃんとカウントアップされた

フォーマッターの設定

人間がいちいち気にする時間が勿体ないので、以下の二点の設定を入れておきたいと思います。

  • ファイル保存時にフォーマッターを実行する設定
  • import文の最適化を行う設定

preferences > Languages & Frameworks > Flutterで設定画面を開き、チェックを入れます。赤枠の項目にチェックを入れます。

ここまででAndroidの設定は一旦完了です。
次はiOSの設定を行いたいと思います。

iOS向けの設定

Xcodeのインストール

  1. AppStoreからXcodeをインストールする
  2. CLI(コマンドラインツール)を設定する
    sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
    sudo xcodebuild -runFirstLaunch
  3. ライセンスに同意する
    sudo xcodebuild -license

iOS シミュレータの設定

ターミナルからopen -a Simulatorで開くこともできますが、基本は Android Struio で開発するので、そこから開く方法で進めます。

  1. Android Studio を開く
  2. 画面上部のFlutter Device Selectionプルダウンで、Open iOS Simuratorを選択する
    • デフォルトだと iPhone 8 のエミュレート画面が立ち上がる
  3. 最後に、サンプルプロジェクトをエミュレータで表示する
    • iPhone 8 のエミュレート画面を立ち上げた後、▶︎ボタンでmain.dartを実行すると、エミュレータ画面に対象のアプリケーションが描画される

      こちらもちゃんと動いてくれた

Webの設定

こちらはキャプチャは省きますが、以下の手順で Android や iOS と同様に動作確認を行うことができます。

  1. Android Studio を開く
  2. 画面上部のFlutter Device Selectionプルダウンで、Chrome(web)を選択する
    • Chromeの画面が立ち上がる
  3. ▶︎ボタンでmain.dartを実行する

Hot Reload

エミュレーション画面でmain.dartを実行した状態で、main.dartのソースコードを変更して保存(command+S)すると、そのタイミングでエミュレート画面がリロードされて、変更が反映されます。
試しに、

  • カラーテーマ
    primarySwatch: Colors.pink,
  • AppBarのタイトル部分
    home: MyHomePage(title: 'Flutter Demo Home Page'),

をなどを変更してみるといいと思います。
自分の場合は、コードを修正したら無意識にCommand+Sで保存する癖があるので、無意識にリアルタイムで変更がアプリ画面に反映されて、とても良い開発体験でした。

ちなみに、Hot Reload は、こちらにあるように、Widget ツリーをリビルドするもので、状態(state)は失いません。つまり、build()は実行するけど、main()initState()は実行しません。
それらが必要な場合は、▶︎ボタン(もしくはctrl+R)でアプリを Restart する必要があります。

実機デプロイ

iOS

Android Studioを使う場合

Android Studio から、エミュレーターにアプリをデプロイして実行するのと同じように、実機に対してもデプロイができます。

  1. 実機(試したのはiPhone8)をPCにつなぐ
  2. Android Studio を開くと、Flutter Device Selectionプルダウンに実機のデバイスが表示される
  3. ▶︎ボタンをクリックすると、アプリが実機にデプロイされる
    • ▶︎の代わりにRun > Flutter Run main.dart in Release Modeを実行することで、リリースモードでデプロイできる
  4. 実機で、アプリアイコンをタップすると「信頼されてないデベロッパ」と表示されるので「信頼」する
    • 設定 > 一般 > デバイス管理 > デベロッパAPPとタップしていく
    • 対象のデベロッパを開いて「信頼」をタップ
  5. ボタンを再度クリックする
    • 無事、実機でアプリ画面が起動された
    • ただし、この時点ではPCとスマホの接続を切ると以下のエラーが発生する
      • In iOS 14+, debug mode Flutter apps can only be launched from Flutter tooling, IDEs with Flutter plugins or from Xcode. Alternatively, build in profile or release modes to enable launching from the home screen.
      • Flutter アプリは、iOS14+ではデバックツールと接続してない場合は、動かないようになっているらしい
    • リリースビルドしたい場合は、Run > Flutter Run 'xxx.dart'' in Release Modeを実行する

自分は、Android Studioを使ってるので基本はこちらを利用しています。

xCodeを使う場合

こちら にあるように、xCodeからも実機にアプリをデプロイして実行することができます。

  1. 依存関係を管理する cocoapods をインストールする
    sudo gem install cocoapods
  2. プロジェクトのルートディレクトリで以下を実行
    open ios/Runner.xcworkspace
  3. 実機(試したのはiPhone8)をPCにつなぐ
  4. 左のメニューからRunnerを選択し、Signing & Capabilitiesタブに移動して、Add Account...で自分のアカウントを追加する
  5. デプロイしたいデバイスをプルダウンから選択し、▶︎ボタンをクリック
  6. 実機で、アプリアイコンをタップすると「信頼されてないデベロッパ」と表示されるので「信頼」する
    • 設定 > 一般 > デバイス管理 > デベロッパAPPとタップしていく
    • 対象のデベロッパを開いて「信頼」をタップ
  7. ▶︎ボタンを再度クリックする
    • リリースビルドしたい場合は、Product > Scheme > Edit Schemeで以下の設定画面を開き、Debug ConfigurationReleaseにして▶︎ボタンでデプロイすれば良い

xCodeだと、iOS固有の設定を変更できて、設定ファイルに反映することができるみたいです。
自分は、Background Fetchを試してみてたのですが、その場合は、xCodeから設定しました。
また、いつ実行されるかわからないBackground FetchDebug > Simurate Background Fetchで明示的にデバッグ実行することもできたりしました。
なので、用途によって Android Studio と xCode を使い分けると良さそうです。

Android

こちら にあるように以下の作業が必要でした。

  1. 実機(試したのはHUAWEI P20 lite)をPCにつなぐ
  2. 「写真を転送」を選択する
  3. 設定 > システム > 端末情報を開き、ビルド番号を7回タップする
  4. PIN(ロック画面のパスワード)を入力する
  5. 設定 > システム > 開発者向けオプションを開き、USBデバッグをONにする
  6. Android Studio を開くと、Flutter Device Selectionプルダウンに実機のデバイスが表示される
  7. ▶︎ボタンをクリックすると、アプリが実機にデプロイされる
    • ▶︎の代わりにRun > Flutter Run main.dart in Release Modeを実行することで、リリースモードでデプロイできる

最後に

Flutter をインストールして、Android/iOS/Web の動作確認が行えるエミュレート環境を構築し、かつ実機へのデプロイまで試してみました。
環境もうまく構築できたので、これから Flutter アプリ開発をちょっと頑張ってみようと思います。