はじめに
Flutterで開発するにあって無くてはならないpackageであるfreezedを改めてまとめておきます
コピペするだけで使えるようにしておきますので使用してみてください
ちゃんと知りたい人は公式ドキュメントをご覧ください
https://pub.dev/packages/freezed
なるべく楽したい人は↓へ
パッケージ導入
何も考えず下記のコマンドを1つずつ実行してpackageを入れてください
全部使います
flutter pub add freezed_annotation
flutter pub add --dev build_runner
flutter pub add --dev freezed
flutter pub add json_annotation
flutter pub add --dev json_serializable
flutter pub add analyzer
flutter pub get
ファイル設定
(project)
- analysis_options.yaml // 編集するファイル
- build.yaml // 追加するファイル
- pubspec.yaml // このファイルと同じ階層にファイル作ってください
何も考えずにanalysis_options.yamlにコピペして追加してください
自動生成されたファイルはlintエラーになるのでこの対応が必須です
analyzer:
errors:
invalid_annotation_target: ignore
exclude:
- "**/*.g.dart"
- "**/*.freezed.dart"
何も考えずにbuild.yamlにコピペして追加してください
build.yamlがない場合は新規作成してください
targets:
$default:
builders:
source_gen|combining_builder:
options:
build_extensions:
'^lib/{{}}.dart': 'lib/generated/{{}}.g.dart'
freezed:
options:
build_extensions:
'^lib/{{}}.dart': 'lib/generated/{{}}.freezed.dart'
pubspec.yamlのgenerateがtrueになっているとファイルの自動生成に失敗するのでご注意を
// generate: true
generate: false
モデルクラスの作成
APIでもSQLでも使えるようにモデルクラスを作成しました
何も考えずにコピペして追加してください
jsonのkeyを指定したり、defaultを指定できるのでソースを確認してみてください
freezedとJsonSerializableの2種類があるのですが、
値を編集する動的なモデルクラスならfreezed
値を参照する静的なモデルクラスならJsonSerializablを使用してください
めんどくさい場合はfreezedに統一してください
import 'package:freezed_annotation/freezed_annotation.dart';
part '../../generated/model/notice.freezed.dart';
part '../../generated/model/notice.g.dart';
/// お知らせフラグ
class NoticeFlag {
/// 既読フラグ(0=未読)
static const int unread = 0;
/// 既読フラグ(1=既読)
static const int read = 1;
}
@freezed
class Notice with _$Notice {
/// コンストラクタ
const factory Notice({
/// お知らせID
required int id,
/// タイトル
required String title,
/// メッセージ内容
required String message,
/// 既読フラグ(0=未読、1=既読)
@Default(0) int isUnread,
}) = _Notice;
/// json -> モデルクラス
factory Notice.fromJson(Map<String, dynamic> json) => _$NoticeFromJson(json);
// freezedはtoJsonを標準装備している
// Map<String, dynamic> toJson()
}
@JsonSerializable()
class NoticeList {
// lintツール sort_unnamed_constructors_first
const NoticeList({required this.noticeList});
// lintツール sort_constructors_first
/// json -> モデルクラス
factory NoticeList.fromJson(Map<String, dynamic> json=>
_$NoticeListFromJson(json);
/// お知らせリスト(json key指定)
@JsonKey(name: 'notice_list')
final List<Notice> noticeList;
/// モデルクラス -> json
Map<String, dynamic> toJson() => _$NoticeListToJson(this);
}
コマンド実行
何も考えすに下記のコマンド実行してください
普段使うなら一番下のコマンドだけで大丈夫です
しかしたまにコンフリクトが起きていたり、ファイルの差分や読み込みがうまくいかないことがあるので、
その場合は下記のコマンド全て実行するとほぼ解決します
(gitで管理しているとよくある)
ちなみに自動生成されるファイルはlib/generated/model配下にあるのでご確認ください
rm pubspec.lock
flutter clean
flutter pub get
flutter pub run build_runner build --delete-conflicting-outputs
動作確認
json←→モデルクラスの変換を実装しているので、下記を参考にしていただければ大体解決するかと思います
copyWithはfreezedでしか使えないのでご注意を
めんどくさい場合はmain()で実行してください
/// Noticeモデル
// json生成
final noticeJson = <String, dynamic>{
'id': 0,
'title': 'タイトル0',
'message': 'メッセージ0',
};
debugPrint('noticeJson = $noticeJson');
// -> noticeJson = {id: 0, title: タイトル0, message: メッセージ0}
// json -> Noticeモデル
final noticeFromJson = Notice.fromJson(noticeJson);
debugPrint('noticeFromJson = $noticeFromJson');
// -> noticeFromJson = Notice(id: 0, title: タイトル0, message: メッセージ0, isUnread: 0)
// noticeFromJsonの値を変更してコピーする
final noticeCopyWith = noticeFromJson.copyWith(isUnread: NoticeFlag.read);
debugPrint('noticeCopyWith = $noticeCopyWith');
// -> noticeCopyWith = Notice(id: 0, title: タイトル0, message: メッセージ0, isUnread: 1)
// Noticeモデル生成
const noticeModel = Notice(
id: 1,
title: 'タイトル1',
message: 'メッセージ1',
isUnread: NoticeFlag.read,
);
debugPrint('noticeModel = $noticeModel');
// -> noticeModel = Notice(id: 1, title: タイトル1, message: メッセージ1, isUnread: 1)
// Noticeモデル -> json
final noticeToJson = noticeModel.toJson();
debugPrint('noticeToJson = $noticeToJson');
// -> noticeToJson = {id: 1, title: タイトル1, message: メッセージ1, isUnread: 1}
/// NoticeListモデル
// json生成
final noticeListJson = <String, dynamic>{
'notice_list': [noticeJson],
};
debugPrint('noticeListJson = $noticeListJson');
// -> noticeListJson = {notice_list: [{id: 0, title: タイトル0, message: メッセージ0}]}
// json -> NoticeListモデル
final noticeListFromJson = NoticeList.fromJson(noticeListJson);
// NoticeListモデル -> json
debugPrint('noticeListFromJson = ${noticeListFromJson.toJson()}');
// -> noticeListFromJson = {notice_list: [Notice(id: 0, title: タイトル0, message: メッセージ0, isUnread: 0)]}
締め
公式ドキュメントを確認しよう
https://pub.dev/packages/freezed