-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[shared_preferences] Add shared preferences devtool (#8494)
This PR adds the shared_preferences_tool package. This package uses the [devtools_extension](https://pub.dev/packages/devtools_extensions) tooling to create a tool for shared preferences. The idea of this PR came from @kenzieschmoll on this [issue](flutter/flutter#145433). Initially I've published this tool as a [separate package](https://pub.dev/packages/shared_preferences_tools), but this PR aims to bring the functionality to the main shared_preferences package. Once this PR gets merged I'll archive the `shared_preferences_tools` package. https://github.com/flutter/packages/assets/11666470/fcf71145-c330-4397-b62e-c0c4c8bc9f01 ## Pre-launch Checklist - [X] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [X] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [X] I read and followed the [relevant style guides] and ran the auto-formatter. (Unlike the flutter/flutter repo, the flutter/packages repo does use `dart format`.) - [X] I signed the [CLA]. - [X] The title of the PR starts with the name of the package surrounded by square brackets, e.g. `[shared_preferences]` - [X] I [linked to at least one issue that this PR fixes] in the description above. - [X] I updated `pubspec.yaml` with an appropriate new version according to the [pub versioning philosophy], or this PR is [exempt from version changes]. - [X] I updated `CHANGELOG.md` to add a description of the change, [following repository CHANGELOG style]. - [X] I updated/added relevant documentation (doc comments with `///`). - [X] I added new tests to check the change I am making, or this PR is [test-exempt]. - [X] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/packages/blob/main/CONTRIBUTING.md [Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [relevant style guides]: https://github.com/flutter/packages/blob/main/CONTRIBUTING.md#style [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/wiki/Chat [linked to at least one issue that this PR fixes]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview [pub versioning philosophy]: https://dart.dev/tools/pub/versioning [exempt from version changes]: https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#version-and-changelog-updates [following repository CHANGELOG style]: https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#changelog-style [test-exempt]: https://github.com/flutter/flutter/wiki/Tree-hygiene#tests
- Loading branch information
1 parent
f7efc2b
commit 258f6dc
Showing
39 changed files
with
4,581 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 1 addition & 0 deletions
1
packages/shared_preferences/shared_preferences/extension/devtools/.gitignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
build |
1 change: 1 addition & 0 deletions
1
packages/shared_preferences/shared_preferences/extension/devtools/.pubignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
!build |
4 changes: 4 additions & 0 deletions
4
packages/shared_preferences/shared_preferences/extension/devtools/config.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
name: shared_preferences | ||
issueTracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22 | ||
version: 1.0.0 | ||
materialIconCodePoint: '0xe683' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
138 changes: 138 additions & 0 deletions
138
...ed_preferences/shared_preferences/lib/src/shared_preferences_devtools_extension_data.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
// 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:convert'; | ||
import 'dart:developer' as developer; | ||
|
||
import 'package:flutter/foundation.dart'; | ||
|
||
import '../shared_preferences.dart'; | ||
|
||
const String _eventPrefix = 'shared_preferences.'; | ||
|
||
/// A typedef for the post event function. | ||
@visibleForTesting | ||
typedef PostEvent = void Function( | ||
String eventKind, | ||
Map<String, Object?> eventData, | ||
); | ||
|
||
/// A helper class that provides data to the DevTools extension. | ||
/// | ||
/// It is only visible for testing and eval. | ||
@visibleForTesting | ||
class SharedPreferencesDevToolsExtensionData { | ||
/// The default constructor for [SharedPreferencesDevToolsExtensionData]. | ||
/// | ||
/// Accepts an optional [PostEvent] that should only be overwritten when testing. | ||
const SharedPreferencesDevToolsExtensionData([ | ||
this._postEvent = developer.postEvent, | ||
]); | ||
|
||
final PostEvent _postEvent; | ||
|
||
/// Requests all legacy and async keys and post an event with the result. | ||
Future<void> requestAllKeys() async { | ||
final SharedPreferences legacyPrefs = await SharedPreferences.getInstance(); | ||
final Set<String> legacyKeys = legacyPrefs.getKeys(); | ||
final Set<String> asyncKeys = await SharedPreferencesAsync().getKeys(); | ||
|
||
_postEvent('${_eventPrefix}all_keys', <String, List<String>>{ | ||
'asyncKeys': asyncKeys.toList(), | ||
'legacyKeys': legacyKeys.toList(), | ||
}); | ||
} | ||
|
||
/// Requests the value for a given key and posts an event with the result. | ||
Future<void> requestValue(String key, bool legacy) async { | ||
final Object? value; | ||
if (legacy) { | ||
final SharedPreferences legacyPrefs = | ||
await SharedPreferences.getInstance(); | ||
value = legacyPrefs.get(key); | ||
} else { | ||
value = await SharedPreferencesAsync().getAll(allowList: <String>{ | ||
key | ||
}).then((Map<String, Object?> map) => map.values.firstOrNull); | ||
} | ||
|
||
_postEvent('${_eventPrefix}value', <String, Object?>{ | ||
'value': value, | ||
// It is safe to use `runtimeType` here. This code | ||
// will only ever run in debug mode. | ||
'kind': value.runtimeType.toString(), | ||
}); | ||
} | ||
|
||
/// Requests the value change for the given key and posts an empty event when finished. | ||
Future<void> requestValueChange( | ||
String key, | ||
String serializedValue, | ||
String kind, | ||
bool legacy, | ||
) async { | ||
final Object? value = jsonDecode(serializedValue); | ||
if (legacy) { | ||
final SharedPreferences legacyPrefs = | ||
await SharedPreferences.getInstance(); | ||
// we need to check the kind because sometimes a double | ||
// gets interpreted as an int. If this was not an issue | ||
// we'd only need to do a simple pattern matching on value. | ||
switch (kind) { | ||
case 'int': | ||
await legacyPrefs.setInt(key, value! as int); | ||
case 'bool': | ||
await legacyPrefs.setBool(key, value! as bool); | ||
case 'double': | ||
await legacyPrefs.setDouble(key, value! as double); | ||
case 'String': | ||
await legacyPrefs.setString(key, value! as String); | ||
case 'List<String>': | ||
await legacyPrefs.setStringList( | ||
key, | ||
(value! as List<Object?>).cast(), | ||
); | ||
} | ||
} else { | ||
final SharedPreferencesAsync prefs = SharedPreferencesAsync(); | ||
// we need to check the kind because sometimes a double | ||
// gets interpreted as an int. If this was not an issue | ||
// we'd only need to do a simple pattern matching on value. | ||
switch (kind) { | ||
case 'int': | ||
await prefs.setInt(key, value! as int); | ||
case 'bool': | ||
await prefs.setBool(key, value! as bool); | ||
case 'double': | ||
await prefs.setDouble(key, value! as double); | ||
case 'String': | ||
await prefs.setString(key, value! as String); | ||
case 'List<String>': | ||
await prefs.setStringList( | ||
key, | ||
(value! as List<Object?>).cast(), | ||
); | ||
} | ||
} | ||
_postEvent('${_eventPrefix}change_value', <String, Object?>{}); | ||
} | ||
|
||
/// Requests a key removal and posts an empty event when removed. | ||
Future<void> requestRemoveKey(String key, bool legacy) async { | ||
if (legacy) { | ||
final SharedPreferences legacyPrefs = | ||
await SharedPreferences.getInstance(); | ||
await legacyPrefs.remove(key); | ||
} else { | ||
await SharedPreferencesAsync().remove(key); | ||
} | ||
_postEvent('${_eventPrefix}remove', <String, Object?>{}); | ||
} | ||
} | ||
|
||
/// Include a variable to keep the library alive in web builds. | ||
/// It must be a `final` variable. | ||
/// Check this discussion for more info: https://github.com/flutter/packages/pull/6749/files/6eb1b4fdce1eba107294770d581713658ff971e9#discussion_r1755375409 | ||
// ignore: prefer_const_declarations | ||
final bool fieldToKeepDevtoolsExtensionLibraryAlive = false; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.