Home

Flutter:Freezed パッケージをインストール・設定・使用する

パッケージとドキュメント

Freezed とは #

Code generation for immutable classes

イミュータブルなデータクラスを作成するためのコードジェネレータです。

データクラスを用意しようとすると数十行のコードを書く必要がありますが、それを毎回手書きしていては大変ですし、タイポによるバグも起きかねません。

...

Duolingo English Test - 初回受験の記録

海外大学院へ進学することを検討しています。

出願にあたり英語の能力証明が求められます。具体的には英語試験にて規定のスコアを取得することです。

検討しているいくつか学校では TOEFL や IELTS などに加えて、Duolingo English Test も利用可能でしたので、私はこの試験を利用することにしました。

...

社会人がコンピュータ・サイエンス(CS)学位を取得する大学の候補

大学でコンピュータ・サイエンスを学びたいと考え、学校を検討した結果をまとめます。同様の思いを持っているの人の役に立てば幸いです。

入学して勉強することが主目的であり学位の取得が本来の目的ではありません。しかしせっかく腰を据えて学習するのであれば、やはりその成果を何かしらの形で残したいと思うものです。ということで、コンピュータ・サイエンスの学位が取得できる大学を検討してみました。

...

ターミナルで実現するシンプルタイマー

小ネタです。Mac で作業していて、ちょっと時間を測りたいなというときに。

さっそく実行 #

以下を実行してみてください。5 秒後に “Hi, It is time.” と再生されるはずです。

...

ブラウザ上でCSVを生成してダウンロードする

ユーザに CSV ファイルをダウンロードさせたいとします。

最初に思いつく方法は、CSV ファイルを作成してどこかのオンラインストレージに配置し、そこからダウンロードさせるというものでしょう。

...

新型コロナウイルス宿泊療養の記録 - 2022年6月

フィリピン帰国後翌日に微熱の発熱があり、その翌朝になっても熱が引かなかったため病院で抗原検査をしたところ、コロナウイルス陽性でした。感染源は不明ですが、医者の方曰く、飛行機内で感染した可能性が高いのではないかとのことでした。

...

フィリピン:Smart のおすすめプロモ

(将来もしまた渡航したときのために、個人的なメモも兼ねて記録。)

お断り:プロモが新規追加・更新されるに従って、本記事の情報が古くなっている可能性もあります。

...

改めて理解するQRコード - その仕組みと歴史

これから QR コードを利用したサービスを開発する予定。

それに向けて改めて QR コードについて調べていたら、非常にすばらしい記事を見かけたので、忘れないように保管しておきます。

...

ブラウザの「戻る/進む」でページが開かれたことを検知する方法

TL;DR #

PerformanceNavigationTiming.type"back_forward" であれば、ブラウザの「戻る/進む」でページが開かれています。

function printNavigationType() {
  const perfEntries = performance.getEntriesByType('navigation');
  perfEntries.forEach((entity) => {
    console.log(entity.type); // e.g. "back_forward"
  });
}

説明 #

  1. ブラウザ環境でグローバルに定義されている performance プロパティからは Performance オブジェクトが取得できます。
  2. Performance オブジェクトの getEntriesByType() メソッドを使うことで PerformanceNavigationTiming オブジェクトが取得できます。
  3. PerformanceNavigationTiming オブジェクトの type プロパティを見ることで、そのページがどのように開かれたのか判定できます。

例えば以下のように判定することができます。

...

TSX ファイル中の関数式でジェネリクスを使うとエラーになる

JSX element 'T' has no corresponding closing tag. #

こんなエラーが出て初めて知りました。長いこと TypeScript 使っていながら意外と知らなかったのでメモ。

関数式でジェネリクスを使うとエラーになる #

const Component: Props = () => {
  // ❌ TS ERROR: JSX element 'T' has no corresponding closing tag.
  const someFunc = <T>(arg: T) => {
    return arg;
  };

  return <p>It's ERROR (;-;)</p>;
};

関数宣言ならばエラーにならない #

const Component: Props = () => {
  // ⭕️ (NO ERROR)
  function someFunc<T>(arg: T) {
    return arg;
  }

  return <p>It's OK (^_^)</p>;
};

関数式でもジェネリクスにカンマをいれるとエラーにならない #

const Component: Props = () => {
  // ⭕️ (NO ERROR) 👇 T の後に "," をつける
  const someFunc = <T,>(arg: T) => {
    return arg;
  };

  return <p>It's OK (^_^)</p>;
};

参考 #

こちらの ISSUE が詳しいです。

...

バリデーションを関数の中に持たせるべきなのかどうか

個人的には結構悩むポイントだったりするので。

/**
 * 関数の中にバリデーションを持たせる場合
 */

doJob();

function doJob(data) {
  if (!validateData(data)) {
    // handle invalid data.
  } else {
    // do job.
  }
}

/**
 * 関数を呼び出す側でバリデーションを行う場合
 */

if (validateData(data)) {
  doJob(data);
}

function doJob(data) {
  // do job.
}

機能的な面でのそれぞれの利点と欠点は以下が考えられます。

...

Firebase Authentication で ソーシャルログインがまれにエラーになる場合

開発しているアプリで Firebase Authentication の Facebook ログインを利用しています。

ただ、挙動に不可思議な点があって、iPhone でごくまれに “Unable to process request” というエラーが出たり、そもそも Facebook にリダイレクトされないことがあったりといった不具合がありました。

...

JavaScript:失敗するたびに待ち時間の間隔を広げていくリトライ処理関数(エクスポネンシャルバックオフ)

関数(TypeScript) #

TypeScript で記載しています。

/** Sleeps for the specified time (milliseconds). */
function sleep(timeMs: number): Promise<void> {
  return new Promise((resolve) => {
    setTimeout(resolve, timeMs);
  });
}

/** Execute function, if it fails, retry after waiting. */
async function tryWithWaiting(
  callback: () => any,
  waitTimeMs: number,
  limitTimeMs: number
): Promise<any> {
  if (waitTimeMs > limitTimeMs) {
    throw new Error('Timeout.');
  }
  const res = callback();
  if (res) {
    return res;
  }
  await sleep(waitTimeMs);
  const extendedWaitTimeMs = waitTimeMs * 2;
  return tryWithWaiting(callback, extendedWaitTimeMs, limitTimeMs);
}

実行結果 #

/** Returns true with a 10% probability or false with a 90% probability. */
function possiblySuccess(): boolean {
  return Math.random() >= 0.9;
}

(async () => {
  try {
    await tryWithWaiting(possiblySuccess, 100, 10_000);
    console.log('SUCCESS (^^)');
  } catch {
    console.log('TIMEOUT (;-;)');
  }
})();

// -> "SUCCESS (^^)" or "TIMEOUT (;-;)"

補足 #

失敗するたびに待ち時間の間隔を広げながらリトライする処理ですが、このアルゴリズムは、エクスポネンシャルバックオフ(Exponential backoff)というらしいです。

...

React:画面が再フォーカスされたときに処理を実行する

例えばメールアドレス認証を行う際、以下のように一度アプリ画面を離れたのち、再び戻ってくるというフローになる場合が多いです。

  1. ユーザがアプリのフォームにアドレスを入力する。
  2. 入力されたメールアドレスにメールを送信する。
  3. ユーザはメーラーアプリでそのメールを確認する。
  4. その後さきほどまで開いていたアプリに戻ってくる。

上記の最後の部分である、アプリに戻ってきたタイミングで何かしらの処理を走らせたいというニーズがあり、カスタムフックを作成しました。

...

JavaScript:オブジェクトの配列から重複を取り除く関数

配列の要素がプリミティブな値の場合、重複を取り除くには Set が便利です。

要素がオブジェクトの場合、Set ではなく Map を利用して重複を排除できます。

以下では Map を利用した重複排除の関数を例示します。

...

Google Play のデベロッパーアカウント作成からアプリのテスト配布(内部テスト)まで - Flutter / Android

自分用メモ。始めて作成した Flutter アプリを Google Play 経由で内部テスト配布したときの手順。

事前注意事項 #

組織名がデフォルトの com.example であるか、またはこれからはじまっているもの(例:com.example.my.app)は、Google Play Console にアップロードするときにエラーとなってしまう。

...

Flutter の状態管理:setState / Provider / Riverpod をコードで見比べる

サンプルコードのウィジェットの階層構造 #

App
 └ Layer1
    └ Layer2
      ├ Layer3A
      └ Layer3B

setState #

import 'package:flutter/material.dart';

void main() => runApp(const App());

class App extends StatelessWidget {
  const App({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: Layer1());
  }
}

class Layer1 extends StatefulWidget {
  const Layer1({Key? key}) : super(key: key);
  @override
  State<Layer1> createState() => _Layer1State();
}

class _Layer1State extends State<Layer1> {
  int _count = 0;
  void _increment() => setState(() => _count++);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Current count is $_count')),
      body: Layer2(count: _count, increment: _increment),
    );
  }
}

class Layer2 extends StatelessWidget {
  const Layer2({Key? key, required this.count, required this.increment})
      : super(key: key);

  final int count;
  final void Function() increment;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        const Text('I am a counter.'),
        Layer3A(count: count),
        Layer3B(increment: increment),
      ],
    );
  }
}

class Layer3A extends StatelessWidget {
  const Layer3A({Key? key, required this.count}) : super(key: key);

  final int count;

  @override
  Widget build(BuildContext context) {
    final String res = count % 2 == 0 ? 'Even' : 'Odd';
    return Text('Count is $res');
  }
}

class Layer3B extends StatelessWidget {
  const Layer3B({Key? key, required this.increment}) : super(key: key);

  final void Function() increment;

  @override
  Widget build(BuildContext context) {
    return TextButton(
      onPressed: increment,
      child: const Text('INCREMENT'),
    );
  }
}

Prop Drilling(バケツリレー)になっています。

...

コンストラクタインジェクション、セッターインジェクション、メソッドインジェクション

本記事は Dart で記載しています。https://dartpad.dev/

DI: Dependency injection #

In software engineering, dependency injection is a technique in which an object receives other objects that it depends on, called dependencies.

Dependency injection - Wikipedia

あるオブジェクトが、自分が依存する別のオブジェクトを受け取ること。

...