What is it, naokirin?

Flutterで、Freezed を使ってみる

最近、個人的にFlutterを使ってみているのですが、データを表現するクラスを作成する際にFreezedというパッケージが非常に便利だったので、紹介したいと思います。

pub.dev

確認したバージョンは以下です。

  • freezed 2.2.0

Freezedとは

Freezedは、データを表現するクラスやJSONとの変換などを簡単に実装できるようにするパッケージです。

データを表現するクラスでは、以下のような複数のクラスで、ボイラープレートコードを実装することが多くあります。

  • コピーできるようにするための、 copyWith メソッド
  • 属性を列挙する文字列に変換する toString メソッド
  • Immutable(不変な)オブジェクトとして operator ==hashCode の実装

これらを自動的に実装したり、JSONとの変換も少数のコードの記載だけで可能にします。

Freezedを使ってみる

Freezedを利用するには、以下の3つの手順を踏むことになります。

  1. 必要なパッケージの導入
  2. コードの実装
  3. build_runner でコードを生成

必要なパッケージの導入

今回は、Flutterへの導入を想定しているため、 flutter pub add コマンドを利用します

flutter pub add freezed_annotation
flutter pub add --dev build_runner
flutter pub add --dev freezed

JSONの変換もしたい場合は以下も追加します。

flutter pub add json_annotation
flutter pub add --dev json_serializable

コードの実装

それではコードを実装します。

// person.dart
import 'package:freezed_annotation/freezed_annotation.dart';

part 'person.freezed.dart';

// Json変換をする場合に必要
part 'person.g.dart';

@freezed
class Person with _$Person {
  const factory Person({
    required String firstName,
    required String lastName,
    required int age,
  }) = _Person;

  factory Person.fromJson(Map<String, Object?> json)
      => _$PersonFromJson(json);
}

軽くコードについて解説しておきます。

まずは、生成したコードを読み込む部分を記載します。

part 'person.freezed.dart';

// Json変換をする場合に必要
part 'person.g.dart';

次にクラスを実装します。

Factoryコンストラクタの引数に、実装したい属性を記載する以外は定型的な実装になります。

@freezed
class Person with _$Person {
  const factory Person({
    required String firstName,
    required String lastName,
    required int age,
  }) = _Person;

  ...
}

最後に fromJson という名称の Factoryコンストラクタを実装すると、JSONとの変換のコードが生成されます。
こちらは、JSONとの変換が不要なら記載する必要はありません。

factory Person.fromJson(Map<String, Object?> json)
    => _$PersonFromJson(json);

build_runner でコードを生成

ここまで実装すると、以下でコードを生成できます。

flutter pub run build_runner build

これにより、 person.freezed.dartperson.g.dart が生成されます。

まとめ

Freezedは、比較的簡単に、データを表現するクラスを実装することができます。

かなり便利なので、Flutterプロジェクトでは、最初から追加するようなパッケージになりそうです。

補足

JSONの変換をする場合にAnalyzeで警告が出る

JSONの変換では、 @JsonKey などのアノテーションを使って、JSONのキーとの対応を指定したりすることがあります。

しかし、これらを利用すると、 flutter analyze で、 invalid_annotation_target という警告が出てしまう場合があります。

これは残念ながら解消が難しいようですので、公式に記載の通り、以下のような形で無視する設定をするしかないようです。

https://pub.dev/packages/freezed#disabling-invalid_annotation_target-warning-and-warning-in-generates-files

If you plan on using Freezed in combination with json_serializable, recent versions of json_serializable and meta may require you to disable the invalid_annotation_target warning.

To do that, you can add the following to the analysis_options.yaml file at the root of your project:

#analysis_options.yaml

analyzer:
  errors:
    invalid_annotation_target: ignore