Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.1.0

* Adds `getAllWithPrefix` and `clearWithPrefix` methods.

## 2.0.17

* Clarifies explanation of endorsement in README.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,16 +106,18 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) {
// We've been committing the whole time.
result.success(true);
break;
case "getAll":
result.success(getAllPrefs());
case "getAllWithPrefix":
String prefix = call.argument("prefix");
result.success(getAllPrefs(prefix));
return;
case "remove":
commitAsync(preferences.edit().remove(key), result);
break;
case "clear":
Set<String> keySet = getAllPrefs().keySet();
case "clearWithPrefix":
String newPrefix = call.argument("prefix");
Set<String> keys = getAllPrefs(newPrefix).keySet();
SharedPreferences.Editor clearEditor = preferences.edit();
for (String keyToDelete : keySet) {
for (String keyToDelete : keys) {
clearEditor.remove(keyToDelete);
}
commitAsync(clearEditor, result);
Expand Down Expand Up @@ -181,12 +183,12 @@ private String encodeList(List<String> list) throws IOException {
}
}

// Filter preferences to only those set by the flutter app.
private Map<String, Object> getAllPrefs() throws IOException {
// Gets all shared preferences, filtered to only those set with the given prefix.
private Map<String, Object> getAllPrefs(String prefix) throws IOException {
Map<String, ?> allPrefs = preferences.getAll();
Map<String, Object> filteredPrefs = new HashMap<>();
for (String key : allPrefs.keySet()) {
if (key.startsWith("flutter.")) {
if (key.startsWith(prefix)) {
Object value = allPrefs.get(key);
if (value instanceof String) {
String stringValue = (String) value;
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class SharedPreferencesAndroid extends SharedPreferencesStorePlatform {
SharedPreferencesStorePlatform.instance = SharedPreferencesAndroid();
}

static const String _defaultPrefix = 'flutter.';

@override
Future<bool> remove(String key) async {
return (await _kChannel.invokeMethod<bool>(
Expand All @@ -37,17 +39,28 @@ class SharedPreferencesAndroid extends SharedPreferencesStorePlatform {

@override
Future<bool> clear() async {
return (await _kChannel.invokeMethod<bool>('clear'))!;
return clearWithPrefix(_defaultPrefix);
}

@override
Future<bool> clearWithPrefix(String prefix) async {
return (await _kChannel.invokeMethod<bool>(
'clearWithPrefix',
<String, dynamic>{'prefix': prefix},
))!;
}

@override
Future<Map<String, Object>> getAll() async {
final Map<String, Object>? preferences =
await _kChannel.invokeMapMethod<String, Object>('getAll');
return getAllWithPrefix(_defaultPrefix);
}

if (preferences == null) {
return <String, Object>{};
}
return preferences;
@override
Future<Map<String, Object>> getAllWithPrefix(String prefix) async {
return (await _kChannel.invokeMapMethod<String, Object>(
'getAllWithPrefix',
<String, dynamic>{'prefix': prefix},
)) ??
<String, Object>{};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: shared_preferences_android
description: Android implementation of the shared_preferences plugin
repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences_android
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22
version: 2.0.17
version: 2.1.0

environment:
sdk: ">=2.17.0 <4.0.0"
Expand All @@ -20,7 +20,7 @@ flutter:
dependencies:
flutter:
sdk: flutter
shared_preferences_platform_interface: ^2.0.0
shared_preferences_platform_interface: ^2.2.0

dev_dependencies:
flutter_test:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,36 @@ void main() {
'plugins.flutter.io/shared_preferences_android',
);

const Map<String, Object> kTestValues = <String, Object>{
const Map<String, Object> flutterTestValues = <String, Object>{
'flutter.String': 'hello world',
'flutter.Bool': true,
'flutter.Int': 42,
'flutter.Double': 3.14159,
'flutter.StringList': <String>['foo', 'bar'],
};
// Create a dummy in-memory implementation to back the mocked method channel
// API to simplify validation of the expected calls.

const Map<String, Object> prefixTestValues = <String, Object>{
'prefix.String': 'hello world',
'prefix.Bool': true,
'prefix.Int': 42,
'prefix.Double': 3.14159,
'prefix.StringList': <String>['foo', 'bar'],
};

const Map<String, Object> nonPrefixTestValues = <String, Object>{
'String': 'hello world',
'Bool': true,
'Int': 42,
'Double': 3.14159,
'StringList': <String>['foo', 'bar'],
};

final Map<String, Object> allTestValues = <String, Object>{};

allTestValues.addAll(flutterTestValues);
allTestValues.addAll(prefixTestValues);
allTestValues.addAll(nonPrefixTestValues);

late InMemorySharedPreferencesStore testData;

final List<MethodCall> log = <MethodCall>[];
Expand All @@ -45,6 +66,12 @@ void main() {
if (methodCall.method == 'getAll') {
return testData.getAll();
}
if (methodCall.method == 'getAllWithPrefix') {
final Map<String, Object?> arguments =
getArgumentDictionary(methodCall);
final String prefix = arguments['prefix']! as String;
return testData.getAllWithPrefix(prefix);
}
if (methodCall.method == 'remove') {
final Map<String, Object?> arguments =
getArgumentDictionary(methodCall);
Expand All @@ -54,6 +81,12 @@ void main() {
if (methodCall.method == 'clear') {
return testData.clear();
}
if (methodCall.method == 'clearWithPrefix') {
final Map<String, Object?> arguments =
getArgumentDictionary(methodCall);
final String prefix = arguments['prefix']! as String;
return testData.clearWithPrefix(prefix);
}
final RegExp setterRegExp = RegExp(r'set(.*)');
final Match? match = setterRegExp.matchAsPrefix(methodCall.method);
if (match?.groupCount == 1) {
Expand All @@ -77,14 +110,21 @@ void main() {

test('getAll', () async {
store = SharedPreferencesAndroid();
testData = InMemorySharedPreferencesStore.withData(kTestValues);
expect(await store.getAll(), kTestValues);
expect(log.single.method, 'getAll');
testData = InMemorySharedPreferencesStore.withData(allTestValues);
expect(await store.getAll(), flutterTestValues);
expect(log.single.method, 'getAllWithPrefix');
});

test('getAllWithPrefix', () async {
store = SharedPreferencesAndroid();
testData = InMemorySharedPreferencesStore.withData(allTestValues);
expect(await store.getAllWithPrefix('prefix.'), prefixTestValues);
expect(log.single.method, 'getAllWithPrefix');
});

test('remove', () async {
store = SharedPreferencesAndroid();
testData = InMemorySharedPreferencesStore.withData(kTestValues);
testData = InMemorySharedPreferencesStore.withData(allTestValues);
expect(await store.remove('flutter.String'), true);
expect(await store.remove('flutter.Bool'), true);
expect(await store.remove('flutter.Int'), true);
Expand All @@ -102,13 +142,13 @@ void main() {
test('setValue', () async {
store = SharedPreferencesAndroid();
expect(await testData.getAll(), isEmpty);
for (final String key in kTestValues.keys) {
final Object value = kTestValues[key]!;
for (final String key in allTestValues.keys) {
final Object value = allTestValues[key]!;
expect(await store.setValue(key.split('.').last, key, value), true);
}
expect(await testData.getAll(), kTestValues);
expect(await testData.getAll(), flutterTestValues);

expect(log, hasLength(5));
expect(log, hasLength(15));
expect(log[0].method, 'setString');
expect(log[1].method, 'setBool');
expect(log[2].method, 'setInt');
Expand All @@ -118,11 +158,36 @@ void main() {

test('clear', () async {
store = SharedPreferencesAndroid();
testData = InMemorySharedPreferencesStore.withData(kTestValues);
testData = InMemorySharedPreferencesStore.withData(allTestValues);
expect(await testData.getAll(), isNotEmpty);
expect(await store.clear(), true);
expect(await testData.getAll(), isEmpty);
expect(log.single.method, 'clear');
expect(log.single.method, 'clearWithPrefix');
});

test('clearWithPrefix', () async {
store = SharedPreferencesAndroid();
testData = InMemorySharedPreferencesStore.withData(allTestValues);

expect(await testData.getAllWithPrefix('prefix.'), isNotEmpty);
expect(await store.clearWithPrefix('prefix.'), true);
expect(await testData.getAllWithPrefix('prefix.'), isEmpty);
});

test('getAllWithNoPrefix', () async {
store = SharedPreferencesAndroid();
testData = InMemorySharedPreferencesStore.withData(allTestValues);

expect(await testData.getAllWithPrefix(''), hasLength(15));
});

test('clearWithNoPrefix', () async {
store = SharedPreferencesAndroid();
testData = InMemorySharedPreferencesStore.withData(allTestValues);

expect(await testData.getAllWithPrefix(''), isNotEmpty);
expect(await store.clearWithPrefix(''), true);
expect(await testData.getAllWithPrefix(''), isEmpty);
});
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.2.0

* Adds `getAllWithPrefix` and `clearWithPrefix` methods.

## 2.1.5

* Clarifies explanation of endorsement in README.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ public class SharedPreferencesPlugin: NSObject, FlutterPlugin, UserDefaultsApi {
UserDefaultsApiSetup.setUp(binaryMessenger: messenger, api: instance)
}

func getAll() -> [String? : Any?] {
return getAllPrefs();
func getAllWithPrefix(prefix: String) -> [String? : Any?] {
return getAllPrefs(prefix: prefix)
}

func setBool(key: String, value: Bool) {
Expand All @@ -42,23 +42,23 @@ public class SharedPreferencesPlugin: NSObject, FlutterPlugin, UserDefaultsApi {
UserDefaults.standard.removeObject(forKey: key)
}

func clear() {
func clearWithPrefix(prefix: String) {
let defaults = UserDefaults.standard
for (key, _) in getAllPrefs() {
for (key, _) in getAllPrefs(prefix: prefix) {
defaults.removeObject(forKey: key)
}
}
}

/// Returns all preferences stored by this plugin.
private func getAllPrefs() -> [String: Any] {
var filteredPrefs: [String: Any] = [:]
if let appDomain = Bundle.main.bundleIdentifier,
let prefs = UserDefaults.standard.persistentDomain(forName: appDomain)
{
for (key, value) in prefs where key.hasPrefix("flutter.") {
filteredPrefs[key] = value
/// Returns all preferences stored with specified prefix.
func getAllPrefs(prefix: String) -> [String: Any] {
var filteredPrefs: [String: Any] = [:]
if let appDomain = Bundle.main.bundleIdentifier,
let prefs = UserDefaults.standard.persistentDomain(forName: appDomain)
{
for (key, value) in prefs where key.hasPrefix(prefix) {
filteredPrefs[key] = value
}
}
return filteredPrefs
}
return filteredPrefs
}
Loading