如何在 Flutter 中将首选项保存到不同的范围?

How to save prefs to different scopes in Flutter?

我正在尝试使用共享首选项以不同方式存储应用程序数据和用户数据,如下所示:

{
    "APP_DATA": {
        "banners": "{\"success\":true,\"data\":{}}",
        "gameList": "{\"success\":true,\"data\":{}}"
    },
    "USER_DATA": 
      {
          "emailVerified": "N",
          "userName": "97144554455",
          "playerToken": "W_8zUx3UCmFPeECjhhjhHhnnsajknHxAM0",
          "idVerified": "UPLOADED",
          "playerId": "412904",
          "bankList": "{\"84\":\"African Bank\",\"5\":\"FNB : First National Bank\"}",
          "unreadMsgCount": "0"
      }
}

但是每当我更新“APP_DATA”或“USER_DATA”中的任何值时,它都会删除以前的值并更新新值。示例:将“banners”和“gamesList”添加到我的 APP_DATA 后,我只看到“gamesList”,因为它覆盖了“banners”值。

  MySharedPreferences.instance.setAppStringValue(
    "banners", jsonEncode(bannersModel),
  );

  MySharedPreferences.instance.setAppStringValue(
    "gamesList", jsonEncode(gamesListModel),
  );

这是我正在使用的功能

  setAppStringValue(String key, String value) async {
    SharedPreferences myPrefs = await SharedPreferences.getInstance();
    myPrefs.setString("APP_DATA", jsonEncode({key: value}));
  }

如何解决这个问题?

使用共享首选项时,它使用唯一键来识别相应数据的值。当您将数据写入键 'APP_DATA' 时,它将覆盖整个字符串值。要更改一个值而不覆盖其余值,您应该将其保存在不同的键中。像这样,

 setAppStringValue(String key, String value) async {
    SharedPreferences myPrefs = await SharedPreferences.getInstance();
    myPrefs.setString("banner", jsonEncode({key: value}));
  }

 setAppStringValue(String key, String value) async {
    SharedPreferences myPrefs = await SharedPreferences.getInstance();
    myPrefs.setString("gamesList", jsonEncode({key: value}));
  }

发生的事情是您用一个全新的值(编码 String)覆盖了 APP_DATA 键,这导致之前的数据丢失。

如果您想保持相同的结构,即 APP_DATA 有一个键,USER_DATA 有另一个键,两者都有自己的数据,您需要获取之前存储的数据并将新数据附加到其中,以确保不会丢失它。

 setAppStringValue(String key, String value) async {
    SharedPreferences myPrefs = await SharedPreferences.getInstance();

    final String storedData = myPrefs.get('APP_DATA');
    final Map newData = {key: value};

    try {
      // Has previous data, decode it and append into the new one
      if (storedData != null) {
        newData.addAll(jsonDecode(storedData));
      }
    } catch (ex) {
      print('Couldn\'t parse the stored data: $ex');
    }

    myPrefs.setString('APP_DATA', jsonEncode(newData));
  }