Skip to content

Commit

Permalink
[shared_preferences] Platform interface for new shared preferences as…
Browse files Browse the repository at this point in the history
…ync (#6962)

Platform interface portion of #5210

Adds new async api
  • Loading branch information
tarrinneal authored Jul 18, 2024
1 parent 976dfce commit b04ff46
Show file tree
Hide file tree
Showing 7 changed files with 340 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## NEXT
## 2.4.0

* Adds `SharedPreferencesAsyncPlatform` API.
* Updates minimum supported SDK version to Flutter 3.16/Dart 3.2.

## 2.3.2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,16 @@ same interface.
# Usage

To implement a new platform-specific implementation of `shared_preferences`, extend
[`SharedPreferencesPlatform`][2] with an implementation that performs the
platform-specific behavior, and when you register your plugin, set the default
`SharedPreferencesLoader` by calling the `SharedPreferencesPlatform.loader` setter.
[`SharedPreferencesPlatform`][2] and [`SharedPreferencesAsyncPlatform`][3] with
implementations that perform the platform-specific behaviors, and when you register
your plugin, set the default `SharedPreferencesStorePlatform` and
`SharedPreferencesAsyncPlatform` by calling the `SharedPreferencesPlatform.instance`
and `SharedPreferencesAsyncPlatform.instance` setters.

Please note that the plugin tooling only registers the native and/or Dart classes
listed in your package's `pubspec.yaml`, so if you intend to implement more than
one class, you will need to manually register the second class
(as can be seen in the Android and iOS implementations).

# Note on breaking changes

Expand All @@ -23,3 +30,4 @@ on why a less-clean interface is preferable to a breaking change.

[1]: ../shared_preferences
[2]: lib/shared_preferences_platform_interface.dart
[3]: lib/shared_preferences_async_platform_interface.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';

import 'shared_preferences_async_platform_interface.dart';
import 'types.dart';

/// Stores data in memory.
///
/// Data does not persist across application restarts. This is useful in unit tests.
base class InMemorySharedPreferencesAsync
extends SharedPreferencesAsyncPlatform {
/// Instantiates an empty in-memory preferences store.
InMemorySharedPreferencesAsync.empty() : _data = <String, Object>{};

/// Instantiates an in-memory preferences store containing a copy of [data].
InMemorySharedPreferencesAsync.withData(Map<String, Object> data)
: _data = Map<String, Object>.from(data);

final Map<String, Object> _data;

@override
Future<bool> clear(
ClearPreferencesParameters parameters,
SharedPreferencesOptions options,
) async {
final PreferencesFilters filter = parameters.filter;
if (filter.allowList != null) {
_data.removeWhere((String key, _) => filter.allowList!.contains(key));
} else {
_data.clear();
}
return true;
}

@override
Future<Map<String, Object>> getPreferences(
GetPreferencesParameters parameters,
SharedPreferencesOptions options,
) async {
final PreferencesFilters filter = parameters.filter;
final Map<String, Object> preferences = Map<String, Object>.from(_data);
preferences.removeWhere((String key, _) =>
filter.allowList != null && !filter.allowList!.contains(key));
return preferences;
}

Future<bool> _setValue(
String key,
Object value,
SharedPreferencesOptions options,
) async {
_data[key] = value;
return true;
}

@override
Future<bool> setString(
String key,
String value,
SharedPreferencesOptions options,
) async {
return _setValue(key, value, options);
}

@override
Future<bool> setInt(
String key,
int value,
SharedPreferencesOptions options,
) async {
return _setValue(key, value, options);
}

@override
Future<bool> setDouble(
String key,
double value,
SharedPreferencesOptions options,
) async {
return _setValue(key, value, options);
}

@override
Future<bool> setBool(
String key,
bool value,
SharedPreferencesOptions options,
) async {
return _setValue(key, value, options);
}

@override
Future<bool> setStringList(
String key,
List<String> value,
SharedPreferencesOptions options,
) async {
return _setValue(key, value, options);
}

@override
Future<String?> getString(
String key,
SharedPreferencesOptions options,
) async {
return _data[key] as String?;
}

@override
Future<bool?> getBool(
String key,
SharedPreferencesOptions options,
) async {
return _data[key] as bool?;
}

@override
Future<double?> getDouble(
String key,
SharedPreferencesOptions options,
) async {
return _data[key] as double?;
}

@override
Future<int?> getInt(
String key,
SharedPreferencesOptions options,
) async {
return _data[key] as int?;
}

@override
Future<List<String>?> getStringList(
String key,
SharedPreferencesOptions options,
) async {
final List<Object>? data = _data[key] as List<Object>?;
return data?.cast<String>();
}

@override
Future<Set<String>> getKeys(
GetPreferencesParameters parameters,
SharedPreferencesOptions options,
) async {
final Set<String> keys = _data.keys.toSet();
if (parameters.filter.allowList != null) {
keys.retainWhere(
(String element) => parameters.filter.allowList!.contains(element));
}

return keys;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';

import 'types.dart';

/// The interface that implementations of shared_preferences_async must implement.
abstract base class SharedPreferencesAsyncPlatform {
/// Constructs a SharedPreferencesAsyncPlatform.
SharedPreferencesAsyncPlatform();

/// The instance of [SharedPreferencesAsyncPlatform] to use.
static SharedPreferencesAsyncPlatform? instance;

/// Stores the String [value] associated with the [key].
Future<void> setString(
String key,
String value,
SharedPreferencesOptions options,
);

/// Stores the bool [value] associated with the [key].
Future<void> setBool(
String key,
bool value,
SharedPreferencesOptions options,
);

/// Stores the double [value] associated with the [key].
Future<void> setDouble(
String key,
double value,
SharedPreferencesOptions options,
);

/// Stores the int [value] associated with the [key].
Future<void> setInt(
String key,
int value,
SharedPreferencesOptions options,
);

/// Stores the List<String> [value] associated with the [key].
Future<void> setStringList(
String key,
List<String> value,
SharedPreferencesOptions options,
);

/// Retrieves the String [value] associated with the [key], if any.
///
/// Throws a [TypeError] if the returned type is not a String.
Future<String?> getString(
String key,
SharedPreferencesOptions options,
);

/// Retrieves the bool [value] associated with the [key], if any.
///
/// Throws a [TypeError] if the returned type is not a bool.
Future<bool?> getBool(
String key,
SharedPreferencesOptions options,
);

/// Retrieves the double [value] associated with the [key], if any.
///
/// Throws a [TypeError] if the returned type is not a double.
Future<double?> getDouble(
String key,
SharedPreferencesOptions options,
);

/// Retrieves the int [value] associated with the [key], if any.
///
/// Throws a [TypeError] if the returned type is not an int.
Future<int?> getInt(
String key,
SharedPreferencesOptions options,
);

/// Retrieves the List<String> [value] associated with the [key], if any.
///
/// Throws a [TypeError] if the returned type is not a List<String>.
Future<List<String>?> getStringList(
String key,
SharedPreferencesOptions options,
);

/// Removes all keys and values in the store that match the given [parameters].
Future<void> clear(
ClearPreferencesParameters parameters,
SharedPreferencesOptions options,
);

/// Returns all key/value pairs persisting in this store that match the given [parameters].
Future<Map<String, Object>> getPreferences(
GetPreferencesParameters parameters,
SharedPreferencesOptions options,
);

/// Returns all keys persisting in this store that match the given [parameters].
Future<Set<String>> getKeys(
GetPreferencesParameters parameters,
SharedPreferencesOptions options,
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,62 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/// Filter options used to get and clear preferences.
// shared_preferences_async types.

import 'package:flutter/foundation.dart';

/// Basic options for creating SharedPreferencesAsync classes.
///
/// This class exists to provide extension to platform specific options as
/// there are currently no general options that are not platform specific.
@immutable
class SharedPreferencesOptions {
/// Constructor for SharedPreferencesOptions.
const SharedPreferencesOptions();
}

/// Filter options used to get and clear preferences on shared_preferences_async.
@immutable
class PreferencesFilters {
/// Creates a new instance with the given options.
const PreferencesFilters({
this.allowList,
});

/// A list of preference keys that will limit getting and clearing to only
/// items included in this list.
///
/// An empty set will create a filter that allows no items to be set/get.
final Set<String>? allowList;
}

/// Parameters for use in [get] methods on shared_preferences_async.
@immutable
class GetPreferencesParameters {
/// Creates a new instance with the given options.
const GetPreferencesParameters({required this.filter});

/// Filter to limit which preferences are returned.
final PreferencesFilters filter;
}

/// Parameters for use in [clear] methods on shared_preferences_async.
@immutable
class ClearPreferencesParameters {
/// Creates a new instance with the given options.
const ClearPreferencesParameters({required this.filter});

/// Filter to limit which preferences are cleared.
final PreferencesFilters filter;
}

//////////////////////////////////
// legacy_shared_preferences types.
//////////////////////////////////
/// Filter options used to get and clear preferences on legacy_shared_preferences.
class PreferencesFilter {
/// Constructor.
/// Creates a new instance with the given options.
PreferencesFilter({
required this.prefix,
this.allowList,
Expand All @@ -19,18 +72,18 @@ class PreferencesFilter {
Set<String>? allowList;
}

/// Parameters for use in [getAll] methods.
/// Parameters for use in [getAll] methods on legacy_shared_preferences.
class GetAllParameters {
/// Constructor.
/// Creates a new instance with the given options.
GetAllParameters({required this.filter});

/// Filter to limit which preferences are returned.
PreferencesFilter filter;
}

/// Parameters for use in [clear] methods.
/// Parameters for use in [clear] methods on legacy_shared_preferences.
class ClearParameters {
/// Constructor.
/// Creates a new instance with the given options.
ClearParameters({required this.filter});

/// Filter to limit which preferences are cleared.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: shared_preferences_platform_interface
description: A common platform interface for the shared_preferences plugin.
repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences_platform_interface
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22
version: 2.3.2
version: 2.4.0

environment:
sdk: ^3.2.0
Expand Down

0 comments on commit b04ff46

Please sign in to comment.