Skip to content

Commit cdd6e13

Browse files
authored
[shared_preferences] fix cast error and mutable list error with getStringList (flutter#7355)
fixes flutter/flutter#153106 fixes flutter/flutter#153112 Will add a follow up pr adding a test to the top level package after this pr lands.
1 parent f7b1256 commit cdd6e13

File tree

20 files changed

+123
-22
lines changed

20 files changed

+123
-22
lines changed

Diff for: packages/shared_preferences/shared_preferences_android/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.3.1
2+
3+
* Fixes `getStringList` returning immutable list.
4+
15
## 2.3.0
26

37
* Adds new `SharedPreferencesAsyncAndroid` API.

Diff for: packages/shared_preferences/shared_preferences_android/example/integration_test/shared_preferences_test.dart

+10
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,16 @@ void main() {
555555
expect(await preferences.getStringList(listKey, emptyOptions), testList);
556556
});
557557

558+
testWidgets('getStringList returns mutable list', (WidgetTester _) async {
559+
final SharedPreferencesAsyncPlatform preferences = await getPreferences();
560+
561+
await preferences.setStringList(listKey, testList, emptyOptions);
562+
final List<String>? list =
563+
await preferences.getStringList(listKey, emptyOptions);
564+
list?.add('value');
565+
expect(list?.length, testList.length + 1);
566+
});
567+
558568
testWidgets('getPreferences', (WidgetTester _) async {
559569
final SharedPreferencesAsyncPlatform preferences = await getPreferences();
560570
await Future.wait(<Future<void>>[

Diff for: packages/shared_preferences/shared_preferences_android/lib/src/shared_preferences_async_android.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ base class SharedPreferencesAsyncAndroid
146146
// is fixed. In practice, the values will never be null, and the native implementation assumes that.
147147
return _convertKnownExceptions<List<String>>(() async =>
148148
(await _api.getStringList(key, _convertOptionsToPigeonOptions(options)))
149-
?.cast<String>());
149+
?.cast<String>()
150+
.toList());
150151
}
151152

152153
Future<T?> _convertKnownExceptions<T>(Future<T?> Function() method) async {

Diff for: packages/shared_preferences/shared_preferences_android/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: shared_preferences_android
22
description: Android implementation of the shared_preferences plugin
33
repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences_android
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22
5-
version: 2.3.0
5+
version: 2.3.1
66

77
environment:
88
sdk: ^3.4.0

Diff for: packages/shared_preferences/shared_preferences_foundation/CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
## NEXT
1+
## 2.5.1
22

3+
* Fixes `getStringList` returning immutable list.
34
* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3.
45

56
## 2.5.0

Diff for: packages/shared_preferences/shared_preferences_foundation/example/integration_test/shared_preferences_test.dart

+10
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,16 @@ void main() {
544544
expect(await preferences.getStringList(listKey, emptyOptions), testList);
545545
});
546546

547+
testWidgets('getStringList returns mutable list', (WidgetTester _) async {
548+
final SharedPreferencesAsyncPlatform preferences = await getPreferences();
549+
550+
await preferences.setStringList(listKey, testList, emptyOptions);
551+
final List<String>? list =
552+
await preferences.getStringList(listKey, emptyOptions);
553+
list?.add('value');
554+
expect(list?.length, testList.length + 1);
555+
});
556+
547557
testWidgets('getPreferences', (WidgetTester _) async {
548558
final SharedPreferencesAsyncPlatform preferences = await getPreferences();
549559
await Future.wait(<Future<void>>[

Diff for: packages/shared_preferences/shared_preferences_foundation/lib/src/shared_preferences_async_foundation.dart

+2-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ base class SharedPreferencesAsyncFoundation
158158
return _convertKnownExceptions<List<String>>(() async =>
159159
((await _api.getValue(key, _convertOptionsToPigeonOptions(options)))
160160
as List<Object?>?)
161-
?.cast<String>());
161+
?.cast<String>()
162+
.toList());
162163
}
163164

164165
@override

Diff for: packages/shared_preferences/shared_preferences_foundation/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: shared_preferences_foundation
22
description: iOS and macOS implementation of the shared_preferences plugin.
33
repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences_foundation
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22
5-
version: 2.5.0
5+
version: 2.5.1
66

77
environment:
88
sdk: ^3.3.0

Diff for: packages/shared_preferences/shared_preferences_linux/CHANGELOG.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
## NEXT
1+
## 2.4.1
22

3+
* Fixes `getStringList` returning immutable list.
4+
* Fixes `getStringList` cast error.
35
* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3.
46

57
## 2.4.0

Diff for: packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart

+25-4
Original file line numberDiff line numberDiff line change
@@ -354,12 +354,15 @@ void main() {
354354
const double testDouble = 3.14159;
355355
const List<String> testList = <String>['foo', 'bar'];
356356

357-
Future<SharedPreferencesAsyncPlatform> getPreferences() async {
357+
Future<SharedPreferencesAsyncPlatform> getPreferences(
358+
{bool clear = true}) async {
358359
final SharedPreferencesAsyncPlatform preferences =
359360
SharedPreferencesAsyncPlatform.instance!;
360-
await preferences.clear(
361-
const ClearPreferencesParameters(filter: PreferencesFilters()),
362-
emptyOptions);
361+
if (clear) {
362+
await preferences.clear(
363+
const ClearPreferencesParameters(filter: PreferencesFilters()),
364+
emptyOptions);
365+
}
363366
return preferences;
364367
}
365368

@@ -397,6 +400,24 @@ void main() {
397400
await preferences.setStringList(listKey, testList, emptyOptions);
398401
expect(await preferences.getStringList(listKey, emptyOptions), testList);
399402
});
403+
testWidgets('getStringList does not throw cast error',
404+
(WidgetTester _) async {
405+
final SharedPreferencesAsyncPlatform preferences = await getPreferences();
406+
407+
await preferences.setStringList(listKey, testList, emptyOptions);
408+
await (preferences as SharedPreferencesAsyncLinux).reload(emptyOptions);
409+
expect(await preferences.getStringList(listKey, emptyOptions), testList);
410+
});
411+
412+
testWidgets('getStringList returns mutable list', (WidgetTester _) async {
413+
final SharedPreferencesAsyncPlatform preferences = await getPreferences();
414+
415+
await preferences.setStringList(listKey, testList, emptyOptions);
416+
final List<String>? list =
417+
await preferences.getStringList(listKey, emptyOptions);
418+
list?.add('value');
419+
expect(list?.length, testList.length + 1);
420+
});
400421

401422
testWidgets('getPreferences', (WidgetTester _) async {
402423
final SharedPreferencesAsyncPlatform preferences = await getPreferences();

Diff for: packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart

+9-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ base class SharedPreferencesAsyncLinux extends SharedPreferencesAsyncPlatform {
253253
SharedPreferencesOptions options,
254254
) async {
255255
final Map<String, Object> data = await _readAll(<String>{key}, options);
256-
return (data[key] as List<String>?)?.toList();
256+
return (data[key] as List<Object?>?)?.cast<String>().toList();
257257
}
258258

259259
@override
@@ -282,6 +282,14 @@ base class SharedPreferencesAsyncLinux extends SharedPreferencesAsyncPlatform {
282282
return _readAll(parameters.filter.allowList, options);
283283
}
284284

285+
/// Reloads preferences from file.
286+
@visibleForTesting
287+
Future<void> reload(
288+
SharedPreferencesLinuxOptions options,
289+
) async {
290+
_cachedPreferences = await _reload(options.fileName);
291+
}
292+
285293
Future<Map<String, Object>> _readAll(
286294
Set<String>? allowList,
287295
SharedPreferencesOptions options,

Diff for: packages/shared_preferences/shared_preferences_linux/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: shared_preferences_linux
22
description: Linux implementation of the shared_preferences plugin
33
repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences_linux
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22
5-
version: 2.4.0
5+
version: 2.4.1
66

77
environment:
88
sdk: ^3.3.0

Diff for: packages/shared_preferences/shared_preferences_web/CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
## NEXT
1+
## 2.4.2
22

3+
* Fixes `getStringList` returning immutable list.
34
* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4.
45

56
## 2.4.1

Diff for: packages/shared_preferences/shared_preferences_web/example/integration_test/shared_preferences_web_test.dart

+10
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,16 @@ void main() {
444444
expect(await preferences.getStringList(listKey, emptyOptions), testList);
445445
});
446446

447+
testWidgets('getStringList returns mutable list', (WidgetTester _) async {
448+
final SharedPreferencesAsyncPlatform preferences = await getPreferences();
449+
450+
await preferences.setStringList(listKey, testList, emptyOptions);
451+
final List<String>? list =
452+
await preferences.getStringList(listKey, emptyOptions);
453+
list?.add('value');
454+
expect(list?.length, testList.length + 1);
455+
});
456+
447457
testWidgets('getPreferences', (WidgetTester _) async {
448458
final SharedPreferencesAsyncPlatform preferences = await getPreferences();
449459
await Future.wait(<Future<void>>[

Diff for: packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ base class SharedPreferencesAsyncWeb extends SharedPreferencesAsyncPlatform {
243243
) async {
244244
final Map<String, Object> data =
245245
await _readAllFromLocalStorage(<String>{key}, options);
246-
return data[key] as List<String>?;
246+
return (data[key] as List<String>?)?.toList();
247247
}
248248
}
249249

Diff for: packages/shared_preferences/shared_preferences_web/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: shared_preferences_web
22
description: Web platform implementation of shared_preferences
33
repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences_web
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22
5-
version: 2.4.1
5+
version: 2.4.2
66

77
environment:
88
sdk: ^3.4.0

Diff for: packages/shared_preferences/shared_preferences_windows/CHANGELOG.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
## NEXT
1+
## 2.4.1
22

3+
* Fixes `getStringList` returning immutable list.
4+
* Fixes `getStringList` cast error.
35
* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3.
46

57
## 2.4.0

Diff for: packages/shared_preferences/shared_preferences_windows/example/integration_test/shared_preferences_test.dart

+26-4
Original file line numberDiff line numberDiff line change
@@ -354,12 +354,15 @@ void main() {
354354
const double testDouble = 3.14159;
355355
const List<String> testList = <String>['foo', 'bar'];
356356

357-
Future<SharedPreferencesAsyncPlatform> getPreferences() async {
357+
Future<SharedPreferencesAsyncPlatform> getPreferences(
358+
{bool clear = true}) async {
358359
final SharedPreferencesAsyncPlatform preferences =
359360
SharedPreferencesAsyncPlatform.instance!;
360-
await preferences.clear(
361-
const ClearPreferencesParameters(filter: PreferencesFilters()),
362-
emptyOptions);
361+
if (clear) {
362+
await preferences.clear(
363+
const ClearPreferencesParameters(filter: PreferencesFilters()),
364+
emptyOptions);
365+
}
363366
return preferences;
364367
}
365368

@@ -398,6 +401,25 @@ void main() {
398401
expect(await preferences.getStringList(listKey, emptyOptions), testList);
399402
});
400403

404+
testWidgets('getStringList does not throw cast error',
405+
(WidgetTester _) async {
406+
final SharedPreferencesAsyncPlatform preferences = await getPreferences();
407+
408+
await preferences.setStringList(listKey, testList, emptyOptions);
409+
await (preferences as SharedPreferencesAsyncWindows).reload(emptyOptions);
410+
expect(await preferences.getStringList(listKey, emptyOptions), testList);
411+
});
412+
413+
testWidgets('getStringList returns mutable list', (WidgetTester _) async {
414+
final SharedPreferencesAsyncPlatform preferences = await getPreferences();
415+
416+
await preferences.setStringList(listKey, testList, emptyOptions);
417+
final List<String>? list =
418+
await preferences.getStringList(listKey, emptyOptions);
419+
list?.add('value');
420+
expect(list?.length, testList.length + 1);
421+
});
422+
401423
testWidgets('getPreferences', (WidgetTester _) async {
402424
final SharedPreferencesAsyncPlatform preferences = await getPreferences();
403425
await preferences.setString(stringKey, testString, emptyOptions);

Diff for: packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart

+9-1
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ base class SharedPreferencesAsyncWindows
254254
SharedPreferencesOptions options,
255255
) async {
256256
final Map<String, Object> data = await _readAll(<String>{key}, options);
257-
return (data[key] as List<String>?)?.toList();
257+
return (data[key] as List<Object?>?)?.cast<String>().toList();
258258
}
259259

260260
@override
@@ -283,6 +283,14 @@ base class SharedPreferencesAsyncWindows
283283
return _readAll(parameters.filter.allowList, options);
284284
}
285285

286+
/// Reloads preferences from file.
287+
@visibleForTesting
288+
Future<void> reload(
289+
SharedPreferencesWindowsOptions options,
290+
) async {
291+
_cachedPreferences = await _readFromFile(options.fileName);
292+
}
293+
286294
Future<Map<String, Object>> _readAll(
287295
Set<String>? allowList,
288296
SharedPreferencesOptions options,

Diff for: packages/shared_preferences/shared_preferences_windows/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: shared_preferences_windows
22
description: Windows implementation of shared_preferences
33
repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences_windows
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22
5-
version: 2.4.0
5+
version: 2.4.1
66

77
environment:
88
sdk: ^3.3.0

0 commit comments

Comments
 (0)