flutter - Dart で json_annotation を使用して Uint8List を json にシリアル化する方法?

okwaves2024-01-24  4

Uint8List メンバーを持つ単純なクラスを作成しました。

import "package:json_annotation/json_annotation.dart";
part "openvpn.g.dart";

@JsonSerializable()
class OpenVPN extends VPN {
  OpenVPN(Uint8List profile) {
    this.profile = profile;
  }
  /...
  Uint8List profile = null;

ただし、ビルド ランナーを実行して JSON シリアライザーを生成すると、次の結果が得られます。

Could not generate `fromJson` code for `profile`.
None of the provided `TypeHelper` instances support the defined type.
package:my_app/folder/openvpn.dart:19:13
   ╷
19 │   Uint8List profile = null;
   │             ^^^^^^^

この型用に独自のシリアライザーを作成する方法はありますか?それとももっと簡単な方法はありますか? json ファイルに文字列を含めたくないのですが、実際のバイトが必要です。これは小さなファイルなので、json 内のバイト配列として保存するのが合理的です。



------------------------

まず、Uint8List のカスタム JSON コンバータを追加します。

import "dart:typed_data";

import "package:json_annotation/json_annotation.dart";

/// Converts to and from [Uint8List] and [List]<[int]>.
class Uint8ListConverter implements JsonConverter<Uint8List?, List<int>?> {
  /// Create a new instance of [Uint8ListConverter].
  const Uint8ListConverter();

  
  @override
  Uint8List? fromJson(List<int>? json) {
    if (json == null) return null;

    return Uint8List.fromList(json);
  }

  @override
  List<int>? toJson(Uint8List? object) {
    if (object == null) return null;

    return object.toList();
  }

Uint8List プロパティで Uint8ListConverter を使用します。あなたの場合:

import 'dart:typed_data';

import 'package:json_annotation/json_annotation.dart';

import 'uint8_list_converter.dart';

part 'open_vpn.g.dart';

@JsonSerializable(explicitToJson: true)
class OpenVPN {
  OpenVPN({this.profile});

  @Uint8ListConverter()
  Uint8List? profile = null;

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

  Map<String, Object?> toJson() => _$OpenVPNToJson(this);
}

プロジェクトのルートで、次のコマンドを実行します。open_vpn.g.dart パーツファイルを生成するターミナル: dart run build_runner build --delete-conflicting-outputs

1

1

このコードでは、null を返す各行で 2 つのエラーが発生します。「A value of type 'Null'」メソッド 'fromJson' からは返されません。戻り値の型が 'Uint8List'" であるためです。および「タイプ「Null」の値」メソッド 'toJson' から返すことはできません。戻り値の型が 'List<int>'" であるためです。

– レプトン

2021 年 12 月 6 日 13:13



------------------------

OpenVPN シリアル化メソッドで、Uint8List を List に変換します。実装によっては、次のようになります。

class OpenVPN {
  factory OpenVPN.fromJson(dynamic map) {
    return OpenVPN(
        ...
        profile: Uint8List.fromList(map['profile'] ?? []),
    );
  }

  toJson() {
    return {
      ...
      'profile': profile as List<int>,
    };
  }
}

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。