preface

Local actions must be used to save user information or network data during the development process of FLUTTER. There is a local action in the form of key-value in FLUTTER (just like NSUserDefaults in ios).

In addition, the conversion between JSON and objects is described here

JOSN quickly generates a variety of language Model entries

Demo address (contents in the fileManager folder, can replace main comments try effect)

Tips: If you’re storing a lot of data and need a relational database, you can search for other sources

Persistent storage (key-value)

Import shared_preferences

The repository for persistent storage was developed by the Flutter team and is called shared_preferences, but it exists as a third-party repository and therefore needs to be imported manually

flutter pub add shared_preferences
Copy the code

After the import, you can directly import directly to use (generally use prompt import)

import 'package:shared_preferences/shared_preferences.dart';
Copy the code

SharedPreferences is introduced

SharedPreferences is a singleton and is a Future asynchronous function, so we need to call the Future asynchronous function to get the singleton and await it.

General principle: Similar to other three-party caching principles, file information is saved in one copy in memory, and all data is read into memory at one time during initialization

Advantages and disadvantages can be clearly seen: fast access speed, large memory footprint, suitable for saving small information

If you store a large amount of data, or if you need to store complex data, you need to choose another database

Database: Relational database SQLite, Core Data, GreenDao, etc. For non-relational databases, options include Realm and UnQLite. For Key/Value stores, there are Redis, Berkeley DB, Level DB, and so on

You can choose a packaged database based on your needs, typically SQLite or Realm on mobile

SharedPreferences Read and write operations

To store data

By passing key and value, you can store all kinds of basic data, and find that there is no store object (not introduced later).

// This is just a generics demonstration. You can actually call whichever you want
static saveInfo<T>(String key, T value) async {
    // We need to get the singleton object with await
    final manager =  await SharedPreferences.getInstance();
    // The default uses are as follows
    manager.setBool(key, value as bool);
    manager.setDouble(key, value as double);
    manager.setInt(key, value as int);
    manager.setString(key, value as String);
    manager.setStringList(key, value as List<String>);
}
Copy the code

Read the data

By passing the key, you can call the corresponding get method directly.

// This is just a generics demonstration. You can actually call whichever you want
static Future<T> readInfo<T>(String key) async {
    final manager = await SharedPreferences.getInstance();
    return manager.getString(key) as T;
    return manager.getBool(key) as T;
    return manager.getDouble(key) as T;
    return manager.getInt(key) as T;
    return manager.getString(key) as T;
    return manager.getStringList(key) as T;
}
Copy the code

Delete the data

Delete not to say, pass a key to delete

static remove(String key) async {
  final manager =  await SharedPreferences.getInstance();
  manager.remove(key);
}
Copy the code

Json converts and stores objects to and from objects

Shared_preferences shared_preferences does not have the ability to store objects, so we can store objects instead of JSON strings

Therefore, the step you need to understand is the json to object conversion

There is currently no reflection mechanism in Flutter, so friendly one-click conversion is not possible. Currently, Map can only be used as a link. Json and Map can be converted to each other

Conversion between JSON and Map

Through the system prefabricated convert library, to achieve the conversion process

Convert a Map to a jsonString using jsonEncode

final userMap = {
    name: "Marshal".age: 20
}

// Convert map to jsonString
final jsonString = jsonEncode(userMap);
Copy the code

JsonString is converted to a Map by jsonDecode

final jsonString = "{"name":"Marshal","age": 20}";

//jsonString is converted to Map
final jsonMap = jsonDecode(jsonString);
Copy the code

Transformations between objects and maps

Using the UserInfo class as an example, create two methods (each class that needs to be saved implements these two methods)

JsonMap to object: Using the named constructor, you can convert the jsonMap passed to this object

Object to jsonMap: You can use object methods or class methods to convert objects created by this class to Maps

// Select the class name and press CTL + Enter to generate Constructor. Select the attributes that need to be initialized by default to generate the parameterized Constructor
class UserInfo {
  String name;
  int age;

  UserInfo(this.name, this.age);

  // The factory constructor can also be used
  UserInfo.fromJson(Map<String, dynamic> json): name = json['name'], age = json['age'];

  // If you want to write as a protocol, you can inherit the protocol when archiving (json and object interchange, for ease of use), then you can use normal methods instead of constructors
  Map<String, dynamic> toJson() =>
      {'name': name, 'age': age};
}
Copy the code

Indirect conversions between objects and JSON

Convert an object to a JSON string indirectly, using UserInfo as an example

final userInfo = UserInfo("Marshal".20);

// Convert UserInfo to jsonMap
final userMap = userInfo.toJson();

// Then call jsonEncode to convert the map to jsonString
final jsonString = jsonEncode(userMap);

//jsonEncode can only convert a map to JSON by default, so two callbacks are needed to convert an object to a map before converting it
// The same as above
final jsonString2 = jsonEncode(value,
  toEncodable: (Object? value) = > value is UserInfo
      ? value.toJson()
      : throw UnsupportedError('Cannot convert to JSON: $value'));
Copy the code

Convert a JSON string to an object indirectly, using UserInfo as an example

final jsonString = "{"name":"Marshal","age": 20}";

// Convert jsonString to jsonMap
final jsonMap = jsonDecode(jsonString); // Convert to Map

// Convert jsonMap to UserInfo
final userInfo = UserInfo.fromJson(jsonMap);
Copy the code

SharedPreferences Access objects

Store the object. Putting all the previous steps together, store the json string converted by the object

static saveObject(String key, UserInfo value) async { final manager = await SharedPreferences.getInstance(); // You can actually set UserInfo as a generic constraint to inherit (or inherit) a class or implement an interface through which toJson methods are called // Converting a class to jsonString requires calling the corresponding class's toJson methods, Final userMap = value.tojson (); // Then call jsonEncode to convert the map to jsonString final jsonString = jsonEncode(userMap); JsonString2 = jsonEncode(value, toEncodable: = jsonEncode(value, toEncodable: = jsonEncode)) (Object? value) => value is UserInfo ? value.toJson() : throw UnsupportedError('Cannot convert to JSON: $value')); if (jsonString.isEmpty) return; manager.setString(key, jsonString); log('jsonEncode --' + jsonString); }Copy the code

Read the object, combining the previous steps, to read the json string transformed object

static Future<dynamic> readObject(String key) async { final manager = await SharedPreferences.getInstance(); final jsonString = manager.getString(key); if (jsonString ! = null) { final jsonMap = jsonDecode(jsonString); // Convert to Map log('jsonDecode --' + jsonmap.tostring ()); Return userinfo.fromjson (jsonMap); return userinfo.fromjson (jsonMap); } return null; }Copy the code

FileManagerEx(improved access object version, currently does not solve the constructor problem, can only be slightly limited, just for reference)

The last

Shared_preferences is only suitable for storing a small amount of data, such as basic user information, search information, etc. If you need a large amount of data, or relational, you can switch to other preferences

This object and JSON interchange is the main introduction to this chapter