【Flutter】GitHub Actionsを使ってみた

GitHub Actionsを使ってみました。

なんもわからん状態から、FlutterのプロジェクトをBuild・Releaseすることができるようになりました。
いくつかつまづいた点があるので、ここではそれらについて書こうと思います。
※まだベータなので、今後改善されるかもしれません。

つまづきポイント

FlutterのプロジェクトにDartのWorkflowを適用しても動かない

なんとなく、以下のworkflowを設定しました。しかし、うまく動きませんでした。
Flutter用のworkflowを設定する必要がありました。  

f:id:miajimyu:20191104142907p:plain

Flutter用の環境設定には、現状は以下のflutter-actionを使うのが、良さそうです。

f:id:miajimyu:20191104143216p:plain

Releaaseするときに使うsecrets.GITHUB_TOKENがよくわからない

yamlの中に突如登場するsecrets.GITHUB_TOKEN、わからん。

    - name: Push APK to Releases
      uses: ncipollo/release-action@v1
      with:
        artifacts: "build/app/outputs/apk/release/*.apk"
        token: ${{ secrets.GITHUB_TOKEN }}

公式のドキュメントをみると、GitHubGITHUB_TOKENを自動で生成すると記載されていました。

GitHub automatically creates a GITHUB_TOKEN secret to use in your workflow.

help.github.com

でもわざわざyamlで指定するからには、本当はGitHub上のどこかで指定するんでしょ?と疑っていました。
結果は、自動で生成されるため、特に気にせずとも動きました。
疑ってすいませんでした。

Marketplaceの検索がうまくできない

Releaseするために"ncipollo/release-action"をGitHubのMarketplaceで検索しても、うまく出てきませんでした。
"release"で検索すると出てきました。正式な名称が"Create Release"でした。
ここらへんの名称のブレが、GitHub Actionsエコシステムの成熟とともに改善されるといいなと思いました。

なぜこのactionを使おうと思ったのか

上記のactionを使おうと思った理由は、Flutterの公式のドキュメントからリンクされていたためでした。
他によいRelease用のActionがあるかもしれません。

flutter.dev

github.com

結果

github.com

READMEにバッジをつけています。

help.github.com

参考資料

github.blog

help.github.com

学び

GitHub Actions(beta)を使って、FlutterのプロジェクトをBuild/Releaseできるようになった。
ソースコードを管理するGitHub自体にCI/CDの機能があるっていうのは、いいですよね。

【Windows Sysinternals】DebugViewを使ってみた

Windows Sysinternalsの一つであるDebugViewを使って、デバッグ出力をのぞいてみました。

手順

DebugViewを入手する

マイクロソフトのウェブサイトから、DebugViewをダウンロードします。

docs.microsoft.com

ダウンロードページからSysinternals Suiteをダウンロードしてもいいかもしれません。
こちらであれば、他Toolもまとめてダウンロードできます。

docs.microsoft.com

DebugViewのファイル名はDbgview.exeです。

デバッグ出力するToolを用意する

Visual Studioで、コンソールアプリ(C++)の新規プロジェクトを作成します。

HelloWorldを出力するプロジェクトテンプレートを使用しました。
そこに、デバッグ出力するためのOutputDebugStringを追加しました。

#include <iostream>
#include <Windows.h> //追加

int main()
{
    std::cout << "Hello World!\n";

    // 追加
    for (int i = 0; i < 10; i++) {
        Sleep(1000);
        OutputDebugString(TEXT("Hello DebugView\n"));
    }
}

実行

まずDebugView(Dbgview.exe)を起動しておきます。

一方、デバッグ出力するTool側で、どちらかを行います。

結果

f:id:miajimyu:20191019225355p:plain

コマンドプロンプト上にはHello World!が出力されました。
一方DebugView上にはHello DebugViewが出力されていることがわかります。

Timeも表示されるので、処理時間の算出とかにつかえそう。
デバッグ出力用にビルドし直す手間もいらないので楽できそう

動作確認環境

学び

  • 作成したToolのデバッグ出力を、DebugViewを使って確認できる
  • DebugViewをエージェントモードで起動することで、リモートのコンピューター上のデバッグ出力もキャプチャーできるらしい(今回は試していない)

【Flutter】quiver.iterablesの関数を試してみた

quiverというパッケージには色々と便利な関数があると思うので、試してみました。

quiver.iterables library - Dart API

quiver - Dart API docs

関数

concat

iterablesを連結する。

// concat<T>(Iterable<Iterable<T>> iterables) → Iterable<T>
print(concat([
  [1, 2, 3],
  [-1, -2, -3]
]));
// (1, 2, 3, -1, -2, -3)

count

数値を加算して、iterablesを生成する。

// count([num start = 0, num step = 1 ]) → Iterable<num>
print(count().first);
// 0
print(count().take(5));
// (0, 1, 2, 3, 4)
print(count(3).take(5));
// (3, 4, 5, 6, 7)
print(count(3, 2).take(5));
// (3, 5, 7, 9, 11)

cycle

iterablesを循環させながら、iterablesを生成する。

// cycle<T>(Iterable<T> iterable) → Iterable<T>
print(cycle([1, 2, 3]).take(7));
// (1, 2, 3, 1, 2, 3, 1)

enumerate

iterableを入力すると、indexとvalueを扱えるiterableを生成する。

// enumerate<E>(Iterable<E> iterable) → Iterable<IndexedValue<E>>
var e = enumerate(['a', 'b', 'c']);
for (var item in e) {
  print("${item.index}, ${item.value}");
}
// 0, a
// 1, b
// 2, c
print(e.first.index); // 0
print(e.first.value); // a
print(e.last.index); // 2
print(e.last.value); // c
print(e.length); // 3

generate

initial()とnext()をもとに、iterableを生成する。

// generate(dynamic initial(), dynamic next(dynamic o)) → Iterable
print(generate(() => 'Hello', (n) => '$n!'));
// (Hello, Hello!, Hello!!, Hello!!!, Hello!!!!, Hello!!!!!, Hello!!!!!!, ...)

min, max, extent

最小値、最大値、最小値と最大値。

// min<T>(Iterable<T> i, [ Comparator<T> compare ]) → T
print(min([2, 5, 1, 4]).toString());
// 1

// max<T>(Iterable<T> i, [ Comparator<T> compare ]) → T
print(max([2, 5, 1, 4]).toString());
// 5

// extent<T>(Iterable<T> i, [ Comparator<T> compare ]) → Extent<T>
var ext = extent([2, 5, 1, 4]);
print(ext.min); // 1
print(ext.max); // 5

merge

iterableを併合する。前提は、入力のiterableがソート済みでること。

// merge<T>(Iterable<Iterable<T>> iterables, [ Comparator<T> compare ]) → Iterable<T>
var a = ['a', 'a', 'd', 'f'];
var b = ['b', 'c', 'g', 'g'];
print(merge([a, b]));
// ['a', 'a', 'b', 'c', 'd', 'f', 'g', 'g']

// This function assumes the provided iterables are already sorted according to the provided compare function. It will not check for this condition or sort the iterables.
var x = ['6', '1', '5'];
var y = ['3', '2', '4'];
print(merge([x, y]));
// [3, 2, 4, 6, 1, 5]
print(merge([x..sort(), y..sort()]));
// [1, 2, 3, 4, 5, 6]

partition

iterableを指定サイズのリストに分割する。

// partition<T>(Iterable<T> iterable, int size) → Iterable<List<T>>
print(partition([1, 2, 3, 4, 5], 3));
// ([1, 2, 3], [4, 5])
print(partition([1, 2, 3, 4, 5, 6, 7, 8, 9], 3));
// ([1, 2, 3], [4, 5, 6], [7, 8, 9])

range

指定した範囲の数値列を生成する。

// range(num start_or_stop, [ num stop, num step ]) → Iterable<num>
print(range(0, 10));
// (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
print(range(0, 10, 2));
// (0, 2, 4, 6, 8)

zip

すべてのIterableのn番目の要素を、n番目の要素として合わせ持つリストを生成する。

// zip<T>(Iterable<Iterable<T>> iterables) → Iterable<List<T>>
print(zip([
  [1, 2, 3],
  ['a', 'b', 'c']
]));
// ([1, a], [2, b], [3, c])

編集後記

最初は関数の定義を見ても、使い方がよくわからなかった。

zip<T>(Iterable<Iterable<T>> iterables) → Iterable<List<T>>

「Iterable<Iterable> iterables」って、めっちゃiterables多いな。みたいな感じ。
そして、周りに聞ける人もいない。

あれ?もしかしてGitHubのtestフォルダ見れば、使い方がわかるのでは?

見た。

GitHub - google/quiver-dart: A set of utility libraries for Dart

わかった

きっと世の中のできる人は、一次情報をちゃんと見てるんでしょうね。

学び

  • quiver.iterablesには便利な関数がある
  • パッケージは、GitHubのtestやexampleのコードを見ると、使い方がわかる場合がある
  • いくつかの関数はPythonの関数に似ている。GitHubのREADMEにもそう書いてある

concat, count, cycle, enumerate, merge, partition, range, and zip create, transform, or combine Iterables in different ways, similar to Python's itertools.

GitHub - google/quiver-dart: A set of utility libraries for Dart

GitHub Pagesを使ってみた

静的ウェブサイトを簡単に作成・公開することができるGitHub Pagesを使ってみました。

公式サイトを見ながら、2つの方法を試しました。

  • HTMLを用意し、サイト公開する
  • Markdownを用意し、サイト公開する

方法

方法について、いろいろWebで調べてみました。
最もわかりやすかったのは、公式サイトでした。
ですので、最新の公式情報を確認するのが良い思います。

pages.github.com

結果

作成したウェブサイト

https://miajimyu.github.io/
HTML版。
Hello World表示するだけのindex.html。
※もしかしたら、こちらは今後変更することがあるかもかもしれません。

https://miajimyu.github.io/github-pages-markdown-sample/
Markdown版。
MarkdownはThemeを選択した後に表示されたデフォルトのまま。
index.mdと_config.ymlが生成されました。

リポジトリ

github.com

github.com

学び

  • すごく簡単に静的サイト公開することができる
  • 公開方法にはHTMLを用意する方法とMarkdownを用意してHTMLに変換してもらう方法がある
  • <username>.github.ioリポジトリを作成した場合、https://<username>.github.io/のURLで公開される
  • 他のリポジトリを作成した場合、https://<username>.github.io/<リポジトリ名>のURLで公開される

Flutterでbarcode scanする【flutter_barcode_scanner】

Flutterでbarcode scanしてみました。
前回とは別の「flutter_barcode_scanner」というPluginも試してみました。

開発環境

Flutter v1.9.1+hotfix.4

flutter_barcode_scanner | Flutter Package 0.1.7

準備

GitHubにexampleがあるので、これをみれば使用例が分かります。

flutter_barcode_scanner/example at master · AmolGangadhare/flutter_barcode_scanner · GitHub

結果

f:id:miajimyu:20191012150429g:plain

github.com

使った感想

周辺の暗い領域でもバーコードをスキャンする仕様は意外でした。
狙っていないバーコードもスキャンしてしまいそうで、ちょっと不安です。
まだ1.0.0に至っていないので、今後の改良されるかもしれませんね。

こちらのPluginでは、中央の赤いラインが動きます。

メソッドの引数にいくつも種類があったので、いろいろな要求に答えようという雰囲気を感じました。

barcodeScanRes = await FlutterBarcodeScanner.scanBarcode(
        "#ff6666",
        "Cancel",
        true,
        ScanMode.BARCODE,
      );

連続的にスキャンするgetBarcodeStreamReceiverメソッドがありました。

Future<void> startBarcodeScanStream() async {
  FlutterBarcodeScanner.getBarcodeStreamReceiver(
    "#ff6666",
    "Cancel",
    true,
    ScanMode.BARCODE,
  ).listen((dynamic barcode) => print(barcode));
}

動作確認環境

Androidエミュレータ

Pixel 3実機

学び

  • 実際に自分でPluginを使ってみないと、想像していた挙動と違う場合がある

関連記事

miajimyu.hatenablog.com

Flutterでbarcode scanする【barcode_scan】

Flutterでbarcode scanしてみました。
ちょっとつまづいた点もあるので、それも記載します。

開発環境

Flutter v1.9.1+hotfix.4

barcode_scan | Flutter Package 1.0.0

準備

Pluginの準備

pub.devのPluginのページの情報が古かったので(例:barcode_scan: ^0.0.3という記載があるなど)、GitHubの方を参考にしました。

以下のリンクから飛びます。

f:id:miajimyu:20191012115013p:plain
Repository(GitHub) on pub.dev

GitHubにexampleがあるので、これをみれば使用例が分かります。

flutter_barcode_reader/example at master · apptreesoftware/flutter_barcode_reader · GitHub

エラーとその解決

エラー

いざデバッグしようとすると以下のエラーが出ました。

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:preDebugBuild'.
> Android dependency 'androidx.core:core' has different version for the compile (1.0.0) and runtime (1.0.1) classpath. You should manually set the same version via DependencyResolution

ちなみに、pubspec.yamlの記載が「barcode_scan: ^0.0.3」の場合はエラー発生せず、「barcode_scan: ^1.0.0」にしたら発生しました。

解決

android/build.gradleの中のバージョンの指定を変更すると、解決できました。

classpath 'com.android.tools.build:gradle:3.2.1'

classpath 'com.android.tools.build:gradle:3.3.1'

にする

stackoverflow.com

結果

f:id:miajimyu:20191012120214g:plain
Android Pixel3

github.com

使った感想

中央の赤いラインにバーコードを重ねたらスキャンするのかと思ったら、ハイライトされている領域に入ったらスキャンしました。
実物のバーコードスキャナーを使ったことがあるため、最初のうち少し違和感ありました。

二次元バーコードもQRコードも、キビキビとスキャンできます。

iOSの方ではあまり試していませんが、ページ遷移の際に指でちょっかいをだすと、処理が少し固まるような印象がありました。

動作確認環境

Androidエミュレータ

Pixel 3実機

学び

  • barcode scanが簡単にできるPluginがある
  • pub.devのPluginのページの情報は古い場合がある
  • build.gradleの中のバージョンの指定を変更すると、エラーが解決する場合がある

関連記事

miajimyu.hatenablog.com

【Flutter】ThemeDataのprimarySwatchでアプリのテーマを変更する

primarySwatchを指定する

Flutterでアプリのテーマを設定するには、ThemeDataでprimarySwatchを指定します。
下記では、primarySwatchを紫色系、accentColor琥珀色に指定しています。

MaterialApp(
  title: 'Flutter Demo',
  theme: ThemeData(
    primarySwatch: Colors.purple,
    accentColor: Colors.amber,
  ),
  home: MyHomePage(),
);

結果は以下の通り。
テーマカラーが紫色系になっていることが分かります。

primarySwatchを変えてみる

primarySwatchを緑色系に変更してみます。

primarySwatch: Colors.green,

すると、以下のようになります。

変わったところ

  • AppBar
  • Container

変わってないところ

  • FloatingActionButton

FloatingActionButtonのbackgroundColorはデフォルトがThemeData.accentColorなので、primarySwatchを変更しても変わらないようですね。
以下はfloating_action_button.dartの抜粋です。

/// The color to use when filling the button.
///
/// Defaults to [ThemeData.accentColor] for the current theme.
final Color backgroundColor;

Code

ThemeData and primarySwatch in Flutter

学び

Material Designのページも見たほうがいいかもしれない。

material.io