如何将自定义“卡片”保存到 dart/flutter 中的共享首选项?

问题描述 投票:0回答:1

我正在尝试保存进度,又名“卡片”。 https://pub.dev/packages/fsrs

我无法序列化它,因为我猜它不是地图。

因此以下代码不起作用。

import 'package:fsrs/fsrs.dart';
import 'dart:convert';

void main() {
  var f = FSRS();
  var card = Card();
  var now = DateTime(2022, 11, 29, 12, 30, 0, 0);
  print("Now: $now");
  var schedulingCards = f.repeat(card, now);
  // printSchedulingCards(schedulingCards);

var encoded = json.encode(card);
print(encoded);
}

此代码给出:拒绝承诺并出现错误:将对象转换为可编码对象失败:“卡”的实例

我想转换为 json 并不是一个坏主意,因为如果稍后我尝试将其保存到 firestore 中,它会运行良好。

我可以在卡后面放一个 .toString() ,并且我可以将其转换为 json,但我不知道如何将其转换回“卡”。

import 'package:fsrs/fsrs.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';

void main() {
  var f = FSRS();
  var card = Card();
  var now = DateTime(2022, 11, 29, 12, 30, 0, 0);
  print("Now: $now");
  var schedulingCards = f.repeat(card, now);
  // printSchedulingCards(schedulingCards);

var encoded = json.encode(card.toString());
print(encoded);
}

这给出了:

"{\"due\":\"2024-04-29 12:23:55.302Z\",\"stability\":0,\"difficulty\":0,\"elapsedDays\":0,\"scheduledDays\":0,\"reps\":0,\"lapses\":0,\"state\":\"State.newState\",\"lastReview\":\"2024-04-29 12:23:55.302Z\"}"

请帮我从存储状态取回卡片。谢谢!

json flutter dart sharedpreferences store
1个回答
0
投票

如果您不是该软件包的贡献者

fsrc
那么您可以在
Card
上使用扩展,添加例如getter
toJson
和一个返回
fromJson
新实例的静态方法
Card
:

import 'package:fsrs/fsrs.dart';
import 'dart:convert';

extension CardHelper on Card {
  /// Returns a map representation of this.
  Map<String, dynamic> get toJson => {
        'due': due.toIso8601String(),
        'stability': stability,
        'difficulty': difficulty,
        'elapsedDays': elapsedDays,
        'scheduledDays': scheduledDays,
        'reps': reps,
        'state': state.index,
        'lastReview': lastReview.toIso8601String()
      };

  /// Converts a map to an object of type `Card`.
  static Card fromJson(Map<String, dynamic> json) {
    // Validate input
    if (json
        case {
          'due': String due,
          'stability': double stability,
          'difficulty': double difficulty,
          'elapsedDays': int elapsedDays,
          'scheduledDays': int scheduledDays,
          'reps': int reps,
          'state': int state,
          'lastReview': String lastReview
        }) {
      return Card()
        ..due = DateTime.parse(due)
        ..stability = stability
        ..difficulty = difficulty
        ..elapsedDays = elapsedDays
        ..scheduledDays = scheduledDays
        ..reps = reps
        ..state = State.values[state]
        ..lastReview = DateTime.parse(lastReview);
    } else {
      throw JsonUnsupportedObjectError(json,
          cause: 'In CardHelper.fromJson: '
              'Validation failed!');
    }
  }
}

void main() {
  final f = FSRS();
  final card = Card();
  final now = DateTime(2022, 11, 29, 12, 30, 0, 0);
  print("Now: $now");
  var schedulingCards = f.repeat(card, now);

  print(card);
  final jsonString = json.encode(card.toJson);
  final clonedCard = CardHelper.fromJson(json.decode(jsonString));
  print(clonedCard);
}

下面是运行

main
生成的控制台输出:

$ dart main.dart
Now: 2022-11-29 12:30:00.000
{"due":"2024-04-29 15:13:06.341169Z","stability":0.0,"difficulty":0.0,"elapsedDays":0,"scheduledDays":0,"reps":0,"lapses":0,"state":"State.newState","lastReview":"2024-04-29 15:13:06.341664Z"}
{"due":"2024-04-29 15:13:06.341169Z","stability":0.0,"difficulty":0.0,"elapsedDays":0,"scheduledDays":0,"reps":0,"lapses":0,"state":"State.newState","lastReview":"2024-04-29 15:13:06.341664Z"}

或者,您可以利用以下事实:在当前版本中,

Card
方法
toString()
内部使用
jsonEncode
来生成字符串输出。注意:如果作者将来更改
toString()
,下面列出的方法将被破坏。

extension CardHelper on Card{

  /// Creates a clone of the `Card` card where `jsonString` is    `card.toString()`.
  static Card fromJsonString(String jsonString) {
    final json = json.decode(jsonString);
    // Validate input
    if (json
        case {
          'due': String due,
          'stability': double stability,
          'difficulty': double difficulty,
          'elapsedDays': int elapsedDays,
          'scheduledDays': int scheduledDays,
          'reps': int reps,
          'state': String state,
          'lastReview': String lastReview
        }) {
      return Card()
        ..due = DateTime.parse(due)
        ..stability = stability
        ..difficulty = difficulty
        ..elapsedDays = elapsedDays
        ..scheduledDays = scheduledDays
        ..reps = reps
        ..state = State.values
            .firstWhere((element) => element.toString() == state.toString())
        ..lastReview = DateTime.parse(lastReview);
    } else {
      throw JsonUnsupportedObjectError(json,
          cause: 'In CardHelper.fromJson: '
              'Validation failed!');
    }
  }
}

我强烈建议创建一个票证,请求

fsrs
的作者添加方法
toJson
Card
构造函数
Card.fromJson(Map<String, dynamic> json)

© www.soinside.com 2019 - 2024. All rights reserved.