Skip to content

Flutter shareable package of object-oriented classes for local caching of user data in json

License

Notifications You must be signed in to change notification settings

dartoosdev/json_cache

 
 

Repository files navigation

json_cache

json cache logo

EO principles respected here DevOps By Rultor.com

pub license PDD status

build codecov CodeFactor Grade style: lint Hits-of-Code

Contents

Overview

Cache is a hardware or software component that stores data so that future requests for that data can be served faster; the data stored in a cache might be the result of an earlier computation or a copy of data stored elsewhere.

Cache_(computing) (2021, August 22). In Wikipedia, The Free Encyclopedia. Retrieved 09:55, August 22, 2021

JsonCache is an object-oriented package for local caching of user data in json. It can also be considered as a layer on top of Flutter's local storage packages that aims to unify them with a stable and elegant interface — JsonCache.

Why Json?

  • Because most of the local storage packages available for Flutter applications use Json as the data format.
  • There is a one-to-one relationship between Dart's built-in type Map<String, dynamic> and Json, which makes encoding/decoding data in Json a trivial task.

Getting Started

This package gives developers great flexibility by providing a set of classes that can be selected and grouped in various combinations to meet specific cache requirements.

JsonCache is the core interface of this package and represents the concept of cached data. It is defined as:

/// Represents cached data in json format.
abstract class JsonCache {
  /// Frees up storage space.
  Future<void> clear();

  /// Removes cached data located at [key].
  Future<void> remove(String key);

  /// Retrieves cached data located at [key] or null if a cache miss occurs.
  Future<Map<String, dynamic>?> value(String key);

  /// It either updates data located at [key] with [value] or, if there is no
  /// previous data at [key], creates a new cache row at [key] with [value].
  ///
  /// **Note**: [value] must be json encodable.
  Future<void> refresh(String key, Map<String, dynamic> value);
}

It is reasonable to consider each cache entry (a key/data pair) as a group of related data. Thus, it is expected to cache data into groups, where a key represents the name of a single data group. For example:

'profile': {'name': 'John Doe', 'email': '[email protected]', 'accountType': 'premium'};
'preferences': {'theme': {'dark': true}, 'notifications':{'enabled': true}}

Above, the profile key is associated with profile-related data, while the preferences key is associated with the user's preferences.

A typical code for saving the previous profile and preferences data is:

final JsonCache jsonCache = … retrieve one of the JsonCache implementations.
…
await jsonCache.refresh('profile', {'name': 'John Doe', 'email': '[email protected]', 'accountType': 'premium'});
await jsonCache.refresh('preferences', {'theme': {'dark': true}, 'notifications':{'enabled': true}});

Implementations

The library JsonCache contains all classes that implement the JsonCache interface with more in-depth details.

The following sections are an overview of each implementation.

JsonCacheMem

JsonCacheMem is is a thread-safe in-memory implementation of the JsonCache interface. Moreover, it encapsulates a secondary cache or "slower level2 cache". Typically, the secondary cache instance is responsible for the local cache; that is, it is the cache instance that persists data on the user's device.

Typical Usage

Due to the fact that JsonCacheMem is a decorator, you should always pass another JsonCache instance to it whenever you instantiates a JsonCacheMem object. For example:

/// Cache initialization
  final prefs = await SharedPreferences.getInstance();
  final JsonCacheMem jsonCache = JsonCacheMem(JsonCachePrefs(prefs));
  …
  /// Saving profile and preferences data.
  await jsonCache.refresh('profile', {'name': 'John Doe', 'email': '[email protected]', 'accountType': 'premium'});
  await jsonCache.refresh('preferences', {'theme': {'dark': true}, 'notifications':{'enabled': true}});
  …
  /// Retrieving preferences data.
  final Map<String, dynamic>? preferences = await jsonCache.value('preferences');
  …
  /// Frees up cached data before the user leaves the application.
  Future<void> signout() async {
    await jsonCache.clear();
  }
  …
  /// Removes cached data related to a specific user.
  Future<void> signoutId(String userId) async {
    await jsonCache.remove(userId);
  }

Cache Initialization

JsonCacheMem.init is the constructor whose purpose is to initialize the cache upon object instantiation. The data passed to the init parameter is deeply copied to both the internal in-memory cache and the level2 cache.

final LocalStorage storage = LocalStorage('my_data');
  final Map<String, Map<String, dynamic>?> initData = await fetchInfo();
  final JsonCacheMem jsonCache = JsonCacheMem.init(initData, level2:JsonCacheLocalStorage(storage));
  …

JsonCachePrefs

JsonCachePrefs is an implementation on top of the shared_preferences package.

final prefs = await SharedPreferences.getInstance();
  final JsonCache jsonCache = JsonCacheMem(JsonCachePrefs(prefs));
  …

JsonCacheEncPrefs

JsonCacheEncPrefs is an implementation on top of the encrypted_shared_preferences package.

final encPrefs = EncryptedSharedPreferences();
  final JsonCache jsonCache = JsonCacheMem(JsonCacheEncPrefs(encPrefs));
  …

JsonCacheLocalStorage

JsonCacheLocalStorage is an implementation on top of the localstorage package.

final LocalStorage storage = LocalStorage('my_data');
  final JsonCache jsonCache = JsonCacheMem(JsonCacheLocalStorage(storage));
  …

JsonCacheCrossLocalStorage

JsonCacheLocalCrossStorage is an implementation on top of the cross_local_storage package.

final LocalStorageInterface prefs = await LocalStorage.getInstance();
  final JsonCache jsonCache = JsonCacheMem(JsonCacheCrossLocalStorage(prefs));
  …

Demo application

The demo application provides a fully working example, focused on demonstrating the caching API in action. You can take the code in this demo and experiment with it.

To run the demo application:

  git clone https://github.com/dartoos-dev/json_cache.git
  cd json_cache/example/
  flutter run -d chrome

This should launch the demo application on Chrome in debug mode.

Contribute

Contributors are welcome!

  1. Open an issue regarding an improvement, a bug you noticed, or ask to be assigned to an existing one.
  2. If the issue is confirmed, fork the repository, do the changes on a separate branch and make a Pull Request.
  3. After review and acceptance, the PR is merged and closed.

Make sure the commands below passes before making a Pull Request.

  flutter analyze && flutter test

References

About

Flutter shareable package of object-oriented classes for local caching of user data in json

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Dart 100.0%