Flutter basic commands

2018/08/28

Flutter Meetup Tokyo #4

@TatsushiKiryu

About me

Agenda

  • 初めの一歩・困ったらコレ
  • アプリの生成・実行
  • Flutter 自体の更新
  • リンティング・コードフォーマット
  • テスト
  • ビルド
  • 補足:コマンド一覧

初めの一歩・

困ったらコレ

flutter doctor

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, v0.5.1, on Mac OS X 10.13.6 17G65, locale ja-JP)
[!] Android toolchain - develop for Android devices (Android SDK 27.0.1)
    ✗ Android licenses not accepted.  To resolve this, run: flutter doctor --android-licenses
[✓] iOS toolchain - develop for iOS devices (Xcode 9.4.1)
[✗] Android Studio (not installed)
[!] VS Code (version 1.26.1)
[✓] Connected devices (1 available)

! Doctor found issues in 3 categories.

アプリの生成・実行

flutter create

$ flutter create my_app
Creating project my_app...
  my_app/ios/Runner.xcworkspace/contents.xcworkspacedata (created)
  my_app/ios/Runner/Info.plist (created)
  my_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png (created)
  my_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png (created)
  my_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md (created)
  my_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json (created)
  my_app/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png (created)
  my_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png (created)
  my_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png (created)
  my_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png (created)
  my_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png (created)
  my_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png (created)
  my_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png (created)
  my_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png (created)
  my_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json (created)
  my_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png (created)
  my_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png (created)
  my_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png (created)
  my_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png (created)
  my_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png (created)
  my_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png (created)
  my_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png (created)
  my_app/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png (created)
  my_app/ios/Runner/Base.lproj/LaunchScreen.storyboard (created)
  my_app/ios/Runner/Base.lproj/Main.storyboard (created)
  my_app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata (created)
  my_app/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme (created)
  my_app/ios/Flutter/Debug.xcconfig (created)
  my_app/ios/Flutter/Release.xcconfig (created)
  my_app/ios/Flutter/AppFrameworkInfo.plist (created)
  my_app/ios/.gitignore (created)
  my_app/test/widget_test.dart (created)
  my_app/my_app.iml (created)
  my_app/.gitignore (created)
  my_app/.metadata (created)
  my_app/ios/Runner/AppDelegate.h (created)
  my_app/ios/Runner/main.m (created)
  my_app/ios/Runner/AppDelegate.m (created)
  my_app/ios/Runner.xcodeproj/project.pbxproj (created)
  my_app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png (created)
  my_app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png (created)
  my_app/android/app/src/main/res/drawable/launch_background.xml (created)
  my_app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png (created)
  my_app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png (created)
  my_app/android/app/src/main/res/values/styles.xml (created)
  my_app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png (created)
  my_app/android/app/src/main/AndroidManifest.xml (created)
  my_app/android/gradle/wrapper/gradle-wrapper.properties (created)
  my_app/android/.gitignore (created)
  my_app/android/gradle.properties (created)
  my_app/android/settings.gradle (created)
  my_app/pubspec.yaml (created)
  my_app/README.md (created)
  my_app/lib/main.dart (created)
  my_app/android/app/build.gradle (created)
  my_app/android/app/src/main/java/com/example/myapp/MainActivity.java (created)
  my_app/android/build.gradle (created)
  my_app/my_app_android.iml (created)
  my_app/.idea/runConfigurations/main_dart.xml (created)
  my_app/.idea/libraries/Flutter_for_Android.xml (created)
  my_app/.idea/libraries/Dart_SDK.xml (created)
  my_app/.idea/modules.xml (created)
  my_app/.idea/workspace.xml (created)
Wrote 65 files.

Running "flutter packages get" in my_app...                 15.4s

[✓] Flutter is fully installed. (Channel beta, v0.5.1, on Mac OS X 10.13.6 17G65, locale ja-JP)
[!] Android toolchain - develop for Android devices is partially installed; more components are available. (Android SDK 27.0.1)
[✓] iOS toolchain - develop for iOS devices is fully installed. (Xcode 9.4.1)
[✗] Android Studio is not installed. (not installed)
[!] VS Code is partially installed; more components are available. (version 1.26.1)
[✓] Connected devices is fully installed. (1 available)

Run "flutter doctor" for information about installing additional components.

All done! In order to run your application, type:

  $ cd my_app
  $ flutter run

Your main program file is lib/main.dart in the my_app directory.

flutter run

$ cd my_app 
$ flutter run
Launching lib/main.dart on iPhone X in debug mode...
Starting Xcode build...                                          
 ├─Assembling Flutter resources...                    1.2s
 └─Compiling, linking and signing...                  9.0s
Xcode build done.                                           11.5s
Syncing files to device iPhone X...                          4.2s

🔥  To hot reload changes while running, press "r". To hot restart (and rebuild state), press "R".
An Observatory debugger and profiler on iPhone X is available at: http://127.0.0.1:8100/
For a more detailed help message, press "h". To quit, press "q".

flutter install

$ flutter install
Installing com.example.myApp to iPhone X...
Uninstalling old version...

Flutter 自体の更新

flutter upgrade

$ flutter upgrade
Upgrading Flutter from /Users/kiryu/flutter...
Already up to date.

Upgrading engine...
Already up-to-date.

Flutter 0.5.1 • channel beta • https://github.com/flutter/flutter.git
Framework • revision c7ea3ca377 (3 months ago) • 2018-05-29 21:07:33 +0200
Engine • revision 1ed25ca7b7
Tools • Dart 2.0.0-dev.58.0.flutter-f981f09760

Running "flutter packages upgrade" in my_app...             15.8s

flutter channel

$ flutter channel
Flutter channels:
* beta
  dev
  master

$ flutter channel dev
Switching to flutter channel 'dev'...
git: Switched to branch 'dev'
git: Your branch is up to date with 'origin/dev'.

$ flutter upgrade    
Downloading Dart SDK from Flutter engine 4b271b2e0265428fc144c5ce6c1234680631d83e...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 85.8M  100 85.8M    0     0  10.4M      0  0:00:08  0:00:08 --:--:-- 11.5M
Building flutter tool...
Upgrading Flutter from /Users/kiryu/flutter...
Already up to date.

Upgrading engine...
Downloading package sky_engine...
Downloading common tools...
Downloading darwin-x64 tools...
Downloading android-arm-profile/darwin-x64 tools...
Downloading android-arm-release/darwin-x64 tools...
Downloading android-arm64-profile/darwin-x64 tools...
Downloading android-arm64-release/darwin-x64 tools...
Downloading android-x86 tools...
Downloading android-x64 tools...
Downloading android-arm tools...
Downloading android-arm-profile tools...
Downloading android-arm-release tools...
Downloading android-arm64 tools...
Downloading android-arm64-profile tools...
Downloading android-arm64-release tools...
Downloading android-arm-dynamic-profile tools...
Downloading android-arm-dynamic-release tools...
Downloading android-arm64-dynamic-profile tools...
Downloading android-arm64-dynamic-release tools...
Downloading ios tools...
Downloading ios-profile tools...
Downloading ios-release tools...

Flutter 0.7.0 • channel dev • https://github.com/flutter/flutter.git
Framework • revision 09fe34708f (5 days ago) • 2018-08-22 10:20:51 -0700
Engine • revision 4b271b2e02
Tools • Dart 2.1.0-dev.1.0.flutter-69fce633b7

Running "flutter packages upgrade" in my_app...             17.5s

リンティング・

コードフォーマット

flutter analyze

$ flutter analyze
Analyzing my_app...                                              

   info • Unused import: 'dart:async' • lib/main.dart:2:8 • unused_import

1 issue found. (ran in 0.8s)

flutter format

$ flutter format .
Formatting directory .:
Unchanged test/widget_test.dart
Formatted lib/main.dart

テスト

flutter test

$ flutter test
00:06 +0: Counter increments smoke test                                                                                   
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure object was thrown running a test:
  Expected: exactly one matching node in the widget tree
  Actual: ?:<zero widgets with text "2" (ignoring offstage widgets)>
   Which: means none were found but one was expected

When the exception was thrown, this was the stack:
#4      main.<anonymous closure> (file:///Users/kiryu/Documents/repo/my_app/test/widget_test.dart:27:5)
<asynchronous suspension>
#5      testWidgets.<anonymous closure>.<anonymous closure> (package:flutter_test/src/widget_tester.dart:72:23)
#6      TestWidgetsFlutterBinding._runTestBody (package:flutter_test/src/binding.dart:555:19)
<asynchronous suspension>
#9      TestWidgetsFlutterBinding._runTest (package:flutter_test/src/binding.dart:539:14)
#10     AutomatedTestWidgetsFlutterBinding.runTest.<anonymous closure> (package:flutter_test/src/binding.dart:883:24)
#16     AutomatedTestWidgetsFlutterBinding.runTest (package:flutter_test/src/binding.dart:880:15)
#17     testWidgets.<anonymous closure> (package:flutter_test/src/widget_tester.dart:71:22)
#18     Declarer.test.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test/src/backend/declarer.dart:168:27)
<asynchronous suspension>
#19     Invoker.waitForOutstandingCallbacks.<anonymous closure> (package:test/src/backend/invoker.dart:249:15)
<asynchronous suspension>
#24     Invoker.waitForOutstandingCallbacks (package:test/src/backend/invoker.dart:246:5)
#25     Declarer.test.<anonymous closure>.<anonymous closure> (package:test/src/backend/declarer.dart:166:33)
#30     Declarer.test.<anonymous closure> (package:test/src/backend/declarer.dart:165:13)
<asynchronous suspension>
#31     Invoker._onRun.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test/src/backend/invoker.dart:403:25)
<asynchronous suspension>
#45     _Timer._runTimers (dart:isolate/runtime/libtimer_impl.dart:382:19)
#46     _Timer._handleMessage (dart:isolate/runtime/libtimer_impl.dart:416:5)
#47     _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
(elided 28 frames from class _FakeAsync, package dart:async, and package stack_trace)

This was caught by the test expectation on the following line:
  file:///Users/kiryu/Documents/repo/my_app/test/widget_test.dart line 27

The test description was:
Counter increments smoke test
════════════════════════════════════════════════════════════════════════════════════════════════════
00:06 +0 -1: Counter increments smoke test [E]                                                                            
  Test failed. See exception logs above.
  The test description was: Counter increments smoke test
  
00:06 +0 -1: Some tests failed.  

ビルド

flutter build

$ flutter build
Flutter build commands.

Usage: flutter build <subcommand> [arguments]
-h, --help    Print this usage information.

Available subcommands:
  aot      Build an ahead-of-time compiled snapshot of your app's Dart code.
  apk      Build an Android APK file from your app.
  bundle   Build the Flutter assets directory from your app.
  flx      Deprecated
  ios      Build an iOS application bundle (Mac OS X host only).

Run "flutter help" to see global options.

補足:コマンド一覧

$ flutter
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.
  fuchsia_reload    Hot reload on Fuchsia.
  help              Display help information for flutter.
  install           Install a Flutter app on an attached device.
  logs              Show log output for running Flutter apps.
  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.

所感

  • ビルドやテスト、スキャフォールドなどの環境周りのコマンドサポートが手厚い。
  • Flutter のアップグレードも簡単。
  • 環境周りで問題が発生したら、大抵は  flutter doctor 解決できる。
  • 総じて、Flutter では必要なコマンドが予め用意されているので、アプリ開発に注力できる。

Happy Fluttering!

Flutter basic commands

By Tatsushi Kiryu

Flutter basic commands

  • 2,547