Flutter入門してDartでHelloWorld

あまり詳しく説明せず、作業ログのような形で書く。
Flutter開発の環境構築、DartでHello World表示までやってみた。

（記事を投稿した翌日にFlutter1.0が公開されたので更新）

# 環境

```
Android Studio 3.2.1
Build #AI-181.5540.7.32.5056338, built on October 9, 2018
JRE: 1.8.0_152-release-1136-b06 x86_64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
macOS 10.14.1
```

### 自分のスペック

- メインはAndroid開発
- iOSはObjective-cは5年以上前に自作アプリ作った程度
- FlutterもDartも触ったことのない完全に素人状態から入門

# まず公式HP

https://flutter.io/

上記公式HPの`Native Performance`にあるUIとTransitionがカッコいい
いつかFlutterでああいうアプリが作ってみたい

# Flutter開発の環境構築

## Flutter SDKをダウンロード
公式HPのGet startedに進み、**Flutter SDK**をダウンロード

ファイル名：`flutter_macos_v1.0.0-stable.zip`

ファイルサイズは430MBくらい

zipを解凍し、flutterディレクトリをホームに配置した
`/Users/ikemura/flutter`
たぶんどこでもいい

## SDKのパスを通す
.bash_profileにパス追加

```
export PATH=$PATH:`pwd`/flutter/bin
```

これでFlutterコマンドを実行する準備ができた

ためしに`flutter`を実行

```
$ flutter
Manage your Flutter app development.

Common commands:

  flutter create <output directory>
    Create a new Flutter project in the specified directory.

  flutter run [options]
    Run your Flutter application on an attached device or in an emulator.

Usage: flutter <command> [arguments]

Global options:
-h, --help                  Print this usage information.
-v, --verbose               Noisy logging, including all shell commands executed.
                            If used with --help, shows hidden options.

-d, --device-id             Target device id or name (prefixes allowed).
    --version               Reports the version of this tool.
    --suppress-analytics    Suppress analytics reporting when this command runs.
    --bug-report            Captures a bug report file to submit to the Flutter team.
                            Contains local paths, device identifiers, and log snippets.

    --packages              Path to your ".packages" file.
                            (required, since the current directory does not contain a ".packages" file)

Available commands:
  analyze                  Analyze the project's Dart code.
  attach                   Attach to a running application.
  bash-completion          Output command line shell completion setup scripts.
  build                    Flutter build commands.
  channel                  List or switch flutter channels.
  clean                    Delete the build/ directory.
  config                   Configure Flutter settings.
  create                   Create a new Flutter project.
  devices                  List all connected devices.
  doctor                   Show information about the installed tooling.
  drive                    Runs Flutter Driver tests for the current project.
  emulators                List, launch and create emulators.
  format                   Format one or more dart files.
  help                     Display help information for flutter.
  install                  Install a Flutter app on an attached device.
  logs                     Show log output for running Flutter apps.
  make-host-app-editable   Moves host apps from generated directories to non-generated directories so that they can be edited by developers.
  packages                 Commands for managing Flutter packages.
  precache                 Populates the Flutter tool's cache of binary artifacts.
  run                      Run your Flutter app on an attached device.
  screenshot               Take a screenshot from a connected device.
  stop                     Stop your Flutter app on an attached device.
  test                     Run Flutter unit tests for the current project.
  trace                    Start and stop tracing for a running Flutter app.
  upgrade                  Upgrade your copy of Flutter.

Run "flutter help <command>" for more information about a command.
Run "flutter help -v" for verbose help output, including less commonly used options.
```

Flutterのヘルプが表示されればOK

## 依存関係のチェック

セットアップを完了するためにインストールする必要がある依存関係があるかどうかを、`flutter doctor`コマンドで確認できる

```
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, v0.11.13, on Mac OS X 10.14.1 18B75, locale ja-JP)
[!] Android toolchain - develop for Android devices (Android SDK 28.0.3)
    ! Some Android licenses not accepted.  To resolve this, run: flutter doctor --android-licenses
[✗] iOS toolchain - develop for iOS devices
    ✗ 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
    ✗ libimobiledevice and ideviceinstaller are not installed. To install with Brew, run:
        brew update
        brew install --HEAD usbmuxd
        brew link usbmuxd
        brew install --HEAD libimobiledevice
        brew install ideviceinstaller
    ✗ ios-deploy not installed. To install with Brew:
        brew install ios-deploy
    ✗ CocoaPods not installed.
        CocoaPods is used to retrieve the iOS platform side's plugin code that responds to your plugin usage on the Dart side.
        Without resolving iOS dependencies with CocoaPods, plugins will not work on iOS.
        For more info, see https://flutter.io/platform-plugins
      To install:
        brew install cocoapods
        pod setup
[✓] Android Studio
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
[✓] Android Studio (version 3.2)
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
[!] IntelliJ IDEA Community Edition (version 2018.3)
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
[!] VS Code (version 1.29.1)
[!] Connected device
    ! No devices available

! Doctor found issues in 5 categories.
```

色々チェックされてるが、重要なのは以下４つ

- Flutter
- Android toolchain
- iOS toolchain
- Android Studio

`flutter doctor`での`☓`の対応方法は今回はあえて説明しない。
`☓`の箇所に解決コマンドのが載っているし、その通りに従って作業したら簡単に解決できた。

とりあえず`flutter doctor`で以下のように`[✓] `になれば大丈夫

```
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, v0.11.13, on Mac OS X 10.14.1 18B75, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK 28.0.3)
[✓] iOS toolchain - develop for iOS devices (Xcode 10.1)
[✓] Android Studio (version 3.2)
```

# プロジェクトの作成、ビルド

実際にFlutterプロジェクトを作成していく
作成方法は公式に載ってる

## CLI版

エミュレータを起動した状態で

```
cd myapp_terminal
flutter run
```
ビルドに5分くらいかかって、スターターアプリが起動した。

Flutterが無事に動いたのでちょっと感動

## IDE版
Android Studioで作成してみる （IntelliJでもできるらしい）

しかし、**File > New Flutter Project** が見つからない。

キャッシュクリアしても、Flutter/Dartプラグインを入れ直して再起動しても **New Flutter Project** が表示されない。

stackoverflowにも同様の現象が報告されてるが、解決手順を試してもダメ

仕方ないので、CLIで作成したプロジェクトをAndroid Studioで開いてビルドした。

<img width="1440" alt="スクリーンショット 2018-12-04 22.04.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/52227/75fbd919-1805-62f3-abe8-d41046666a6c.png">


# hot reload

lib/main.dart を開いて、テキストを`You havepushedthe button this many times`から`Hello World`に修正し、⌘Sで保存すると、即座に画面に反映された。

これがホットリロードか
また感動

# プロジェクトの中身

Android Studioでプロジェクトの中身を覗いてみる

<img width="328" alt="スクリーンショット 2018-12-04 22.46.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/52227/15e0b1e3-92f8-cd8a-8ee7-9a829a4625fa.png">


主に4つのディレクトリに分かれている

- android
- ios
- lib
- test

ディレクトリを１つずつ見ていく

## androidディレクトリ

パッと見は普通のAndroidプロジェクトに見える。

中を開くと`MainActivity`というjavaファイルがあったが、普通のAndroidのActivityとは作りが違うようだ。

```java
public class MainActivity extends FlutterActivity {  
  @Override  
  protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
  GeneratedPluginRegistrant.registerWith(this);  
  }  
}
```

レイアウトxmlの指定がないし、そもそもプロジェクト内に`layout`ディレクトリすらなかった。

特殊すぎる

## ios

ios/Runnerを開くとAppDelegate.hとAppDelegate.mがある。
これは...objective-cファイルか？

objective-cはもう5年以上さわってないのでほぼ忘れた。
`viewDidLoad`はどこに書くんだっけ？　main.m？
もう分からん、あとの詳しい事は他のiOSエンジニアに任せた。

## libディレクトリ
ここがDartファイルの置き場らしい。

ファイルがmain.dartしかなく、中を覗くと100行しかコードがない
コメントを消すと60行ちょい

ちょっと長いのでGithubのソースリンク
https://github.com/ikemura23/flutter_sample/blob/master/lib/main.dart

これだけでデザインもビジネスロジックも足りてるんだろうか

よく分からないけどすごい

## testディレクトリ
sidget_test.dartファイルがあるのみ。

```dart
void main() {  
  testWidgets('Counter increments smoke test', (WidgetTester tester) async {  
    // Build our app and trigger a frame.  
  await tester.pumpWidget(MyApp());  
  
  // Verify that our counter starts at 0.  
  expect(find.text('0'), findsOneWidget);  
  expect(find.text('1'), findsNothing);  
  
  // Tap the '+' icon and trigger a frame.  
  await tester.tap(find.byIcon(Icons.add));  
  await tester.pump();  
  
  // Verify that our counter has incremented.  
  expect(find.text('0'), findsNothing);  
  expect(find.text('1'), findsOneWidget);  
  });  
}
```

`async / await` という単語が見える、JavaScriptっぽい

# 感想

Flutterには前から興味があったので、実際に触れる事ができて感動した。

もしFlutterでアプリを作るならiOSアプリの知識もないとダメだと感じた。
それ知識がObjective-cかSwiftなのか分からないが...

Dartを初めて見たが、JavaとJavaScriptを混ぜたような印象を受けた。
あとJavaScriptやKotlinを触ってるなら、Dartのこの書き方はすぐ理解できるはず。

```dart
void main() => runApp(MyApp());

上は、たぶん下の省略形

void main() {
  return runApp(myApp());
}
```

Dartで残念なのが、行末のセミコロンは不要であって欲しかった。
JavaScriptでも書く必要ないし、、、
Javaでは必要だからなのか？