Skip to content

Commit

Permalink
support SharedPreferencesWithCache and SharedPreferencesAsync.
Browse files Browse the repository at this point in the history
issue #75
  • Loading branch information
hoc081098 committed Aug 13, 2024
1 parent 897fce0 commit 7d820de
Show file tree
Hide file tree
Showing 8 changed files with 318 additions and 43 deletions.
44 changes: 26 additions & 18 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,10 @@ packages:
dependency: transitive
description:
name: plugin_platform_interface
sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.dev"
source: hosted
version: "2.1.3"
version: "2.1.8"
process:
dependency: transitive
description:
Expand Down Expand Up @@ -275,58 +275,58 @@ packages:
dependency: transitive
description:
name: shared_preferences
sha256: b7f41bad7e521d205998772545de63ff4e6c97714775902c199353f8bf1511ac
sha256: c272f9cabca5a81adc9b0894381e9c1def363e980f960fa903c604c471b22f68
url: "https://pub.dev"
source: hosted
version: "2.2.1"
version: "2.3.1"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06"
sha256: a7e8467e9181cef109f601e3f65765685786c1a738a83d7fbbde377589c0d974
url: "https://pub.dev"
source: hosted
version: "2.2.1"
version: "2.3.1"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7"
sha256: c4b35f6cb8f63c147312c054ce7c2254c8066745125264f0c88739c417fc9d9f
url: "https://pub.dev"
source: hosted
version: "2.3.4"
version: "2.5.2"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
sha256: c2eb5bf57a2fe9ad6988121609e47d3e07bb3bdca5b6f8444e4cf302428a128a
sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
url: "https://pub.dev"
source: hosted
version: "2.3.1"
version: "2.4.1"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a
sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
url: "https://pub.dev"
source: hosted
version: "2.3.1"
version: "2.4.1"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf
sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e
url: "https://pub.dev"
source: hosted
version: "2.2.1"
version: "2.4.2"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
sha256: f763a101313bd3be87edffe0560037500967de9c394a714cd598d945517f694f
sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
url: "https://pub.dev"
source: hosted
version: "2.3.1"
version: "2.4.1"
sky_engine:
dependency: transitive
description: flutter
Expand Down Expand Up @@ -396,6 +396,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "14.2.1"
web:
dependency: transitive
description:
name: web
sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062
url: "https://pub.dev"
source: hosted
version: "1.0.0"
win32:
dependency: transitive
description:
Expand All @@ -413,5 +421,5 @@ packages:
source: hosted
version: "0.2.0+3"
sdks:
dart: ">=3.3.0 <4.0.0"
flutter: ">=3.18.0-18.0.pre.54"
dart: ">=3.4.0 <4.0.0"
flutter: ">=3.22.0"
80 changes: 80 additions & 0 deletions lib/src/impl/async/shared_preferences_async_adapter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:meta/meta.dart';
import 'package:rx_storage/rx_storage.dart';
import 'package:shared_preferences/shared_preferences.dart';

import '../../interface/shared_preferences_like.dart';

/// [SharedPreferencesLike]'s implementation by delegating a [SharedPreferencesAsync].
@experimental
class SharedPreferencesAsyncAdapter implements SharedPreferencesLike {
final SharedPreferencesAsync _prefsAsync;

/// Construct a [SharedPreferencesAdapter] with [SharedPreferencesAsync].
SharedPreferencesAsyncAdapter(this._prefsAsync);

@override
Future<void> clear([void _]) => _prefsAsync.clear();

@override
Future<bool> containsKey(String key, [void _]) =>
_prefsAsync.containsKey(key);

@override
Future<Map<String, Object?>> reload() => _prefsAsync.getAll();

@override
Future<void> remove(String key, [void _]) => _prefsAsync.remove(key);

@override
Future<T?> read<T extends Object>(String key, Decoder<T?> decoder,
[void _]) =>
_prefsAsync.getAll().then((map) => decoder(map[key]));

@override
Future<Map<String, Object?>> readAll([void _]) => _prefsAsync.getAll();

@override
Future<void> write<T extends Object>(
String key, T? value, Encoder<T?> encoder,
[void _]) {
final encodedOrFuture = encoder(value);
return encodedOrFuture is Future<Object?>
? encodedOrFuture.then((encoded) => _write(encoded, key, value))
: _write(encodedOrFuture, key, value);
}

Future<void> _write(Object? encoded, String key, Object? value) {
assert(encoded is! Future<dynamic>,
'The actual type of encoded value is ${encoded.runtimeType}');

if (encoded == null) {
return remove(key);
}
if (encoded is double) {
return _prefsAsync.setDouble(key, encoded);
}
if (encoded is int) {
return _prefsAsync.setInt(key, encoded);
}
if (encoded is bool) {
return _prefsAsync.setBool(key, encoded);
}
if (encoded is String) {
return _prefsAsync.setString(key, encoded);
}
if (encoded is List<String>) {
return _prefsAsync.setStringList(key, encoded);
}

throw PlatformException(
code: SharedPreferencesLike.errorCode,
message:
'The encoded value of $value has the unsupported type (${encoded.runtimeType}). '
'Encoder must return a value of type FutureOr<T> '
'(where T is a supported type (double, int, bool, String or List<String>))',
);
}
}
104 changes: 104 additions & 0 deletions lib/src/impl/async/shared_preferences_with_cache_adapter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:rx_storage/rx_storage.dart';
import 'package:shared_preferences/shared_preferences.dart';

import '../../interface/shared_preferences_like.dart';

/// [SharedPreferencesLike]'s implementation by delegating a [SharedPreferencesWithCache].
class SharedPreferencesWithCacheAdapter implements SharedPreferencesLike {
final SharedPreferencesWithCache _prefsWithCache;

SharedPreferencesWithCacheAdapter._(this._prefsWithCache);

static Future<T> _wrap<T>(T value) => SynchronousFuture<T>(value);

static Future<T> _wrapFutureOr<T>(FutureOr<T> value) =>
value is Future<T> ? value : SynchronousFuture<T>(value);

/// Create [SharedPreferencesAdapter] from [SharedPreferences].
static FutureOr<SharedPreferencesWithCacheAdapter> from(
FutureOr<SharedPreferencesWithCache> prefsOrFuture,
) =>
prefsOrFuture is Future<SharedPreferencesWithCache>
? prefsOrFuture.then((p) => SharedPreferencesWithCacheAdapter._(p))
: SharedPreferencesWithCacheAdapter._(prefsOrFuture)
as FutureOr<SharedPreferencesWithCacheAdapter>;

@override
Future<void> clear([void _]) => _prefsWithCache.clear();

@override
Future<bool> containsKey(String key, [void _]) =>
_wrap(_prefsWithCache.containsKey(key));

@override
Future<Map<String, Object?>> reload() =>
_prefsWithCache.reloadCache().then((_) => _getAllFromPrefs());

@override
Future<void> remove(String key, [void _]) => _prefsWithCache.remove(key);

@override
Future<T?> read<T extends Object>(String key, Decoder<T?> decoder,
[void _]) =>
_wrapFutureOr(decoder(_getFromPrefs(key)));

@override
Future<Map<String, Object?>> readAll([void _]) => _wrap(_getAllFromPrefs());

@override
Future<void> write<T extends Object>(
String key, T? value, Encoder<T?> encoder,
[void _]) {
final encodedOrFuture = encoder(value);
return encodedOrFuture is Future<Object?>
? encodedOrFuture.then((encoded) => _write(encoded, key, value))
: _write(encodedOrFuture, key, value);
}

Object? _getFromPrefs(String key) {
final val = _prefsWithCache.get(key);
return val is List ? _prefsWithCache.getStringList(key) : val;
}

Map<String, Object?> _getAllFromPrefs() {
return {
for (final k in _prefsWithCache.keys) k: _getFromPrefs(k),
};
}

Future<void> _write(Object? encoded, String key, Object? value) {
assert(encoded is! Future<dynamic>,
'The actual type of encoded value is ${encoded.runtimeType}');

if (encoded == null) {
return remove(key);
}
if (encoded is double) {
return _prefsWithCache.setDouble(key, encoded);
}
if (encoded is int) {
return _prefsWithCache.setInt(key, encoded);
}
if (encoded is bool) {
return _prefsWithCache.setBool(key, encoded);
}
if (encoded is String) {
return _prefsWithCache.setString(key, encoded);
}
if (encoded is List<String>) {
return _prefsWithCache.setStringList(key, encoded);
}

throw PlatformException(
code: SharedPreferencesLike.errorCode,
message:
'The encoded value of $value has the unsupported type (${encoded.runtimeType}). '
'Encoder must return a value of type FutureOr<T> '
'(where T is a supported type (double, int, bool, String or List<String>))',
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@ import 'package:flutter/services.dart';
import 'package:rx_storage/rx_storage.dart';
import 'package:shared_preferences/shared_preferences.dart';

import '../interface/shared_preferences_like.dart';
import '../../interface/shared_preferences_like.dart';
import '../async/shared_preferences_async_adapter.dart';
import '../async/shared_preferences_with_cache_adapter.dart';

/// [SharedPreferencesLike]'s implementation by delegating a [SharedPreferences].
///
/// This is a legacy API. For new code,
/// consider [SharedPreferencesAsyncAdapter] or [SharedPreferencesWithCacheAdapter].
class SharedPreferencesAdapter implements SharedPreferencesLike {
final SharedPreferences _prefs;

Expand Down
Loading

0 comments on commit 7d820de

Please sign in to comment.