diff --git a/packages/shared_preferences/shared_preferences_foundation/CHANGELOG.md b/packages/shared_preferences/shared_preferences_foundation/CHANGELOG.md index dbd80f8926d5..4fb4e5381c2d 100644 --- a/packages/shared_preferences/shared_preferences_foundation/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences_foundation/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.5.2 + +* Fixes getting all preferences when suite name is used. + ## 2.5.1 * Fixes `getStringList` returning immutable list. diff --git a/packages/shared_preferences/shared_preferences_foundation/darwin/Tests/RunnerTests.swift b/packages/shared_preferences/shared_preferences_foundation/darwin/Tests/RunnerTests.swift index 88d38022d615..62cfd169b4a4 100644 --- a/packages/shared_preferences/shared_preferences_foundation/darwin/Tests/RunnerTests.swift +++ b/packages/shared_preferences/shared_preferences_foundation/darwin/Tests/RunnerTests.swift @@ -115,6 +115,8 @@ class RunnerTests: XCTestCase { // Async system tests. let emptyOptions = SharedPreferencesPigeonOptions() + let optionsWithSuiteName = SharedPreferencesPigeonOptions( + suiteName: "group.example.sharedPreferencesFoundationExample") func testAsyncSetAndGet() throws { let plugin = SharedPreferencesPlugin() @@ -154,6 +156,19 @@ class RunnerTests: XCTestCase { } + func testAsyncGetAllWithAndWithoutSuiteName() throws { + let plugin = SharedPreferencesPlugin() + + try plugin.set(key: "aKey", value: "hello world", options: emptyOptions) + try plugin.set(key: "aKeySuite", value: "hello world with suite", options: optionsWithSuiteName) + + let storedValues = try plugin.getAll(allowList: nil, options: emptyOptions) + XCTAssertEqual(storedValues["aKey"] as? String, "hello world") + + let storedValuesWithGroup = try plugin.getAll(allowList: nil, options: optionsWithSuiteName) + XCTAssertEqual(storedValuesWithGroup["aKeySuite"] as? String, "hello world with suite") + } + func testAsyncGetAllWithAllowList() throws { let plugin = SharedPreferencesPlugin() diff --git a/packages/shared_preferences/shared_preferences_foundation/darwin/shared_preferences_foundation/Sources/shared_preferences_foundation/SharedPreferencesPlugin.swift b/packages/shared_preferences/shared_preferences_foundation/darwin/shared_preferences_foundation/Sources/shared_preferences_foundation/SharedPreferencesPlugin.swift index ae86be7bab2f..71602ab21e9c 100644 --- a/packages/shared_preferences/shared_preferences_foundation/darwin/shared_preferences_foundation/Sources/shared_preferences_foundation/SharedPreferencesPlugin.swift +++ b/packages/shared_preferences/shared_preferences_foundation/darwin/shared_preferences_foundation/Sources/shared_preferences_foundation/SharedPreferencesPlugin.swift @@ -152,7 +152,13 @@ public class SharedPreferencesPlugin: NSObject, FlutterPlugin, UserDefaultsApi { var filteredPrefs: [String: Any] = [:] var compatiblePrefs: [String: Any] = [:] let allowSet = allowList.map { Set($0) } - if let appDomain = Bundle.main.bundleIdentifier, + + // Since `getUserDefaults` is initialized with the suite name, it seems redundant to call + // `persistentDomain` with the suite name again. However, it is necessary because + // `dictionaryRepresentation` returns keys from the global domain. + // Also, Apple's docs on `persistentDomain` are incorrect, + // see: https://github.com/feedback-assistant/reports/issues/165 + if let appDomain = options.suiteName ?? Bundle.main.bundleIdentifier, let prefs = try getUserDefaults(options: options).persistentDomain(forName: appDomain) { if let allowSet = allowSet { diff --git a/packages/shared_preferences/shared_preferences_foundation/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_foundation/example/integration_test/shared_preferences_test.dart index 672f453e5ecd..e40423d4da56 100644 --- a/packages/shared_preferences/shared_preferences_foundation/example/integration_test/shared_preferences_test.dart +++ b/packages/shared_preferences/shared_preferences_foundation/example/integration_test/shared_preferences_test.dart @@ -487,6 +487,9 @@ void main() { group('shared_preferences_async', () { final SharedPreferencesAsyncFoundationOptions emptyOptions = SharedPreferencesAsyncFoundationOptions(); + final SharedPreferencesAsyncFoundationOptions optionsWithSuiteName = + SharedPreferencesAsyncFoundationOptions( + suiteName: 'group.example.sharedPreferencesFoundation'); const String stringKey = 'testString'; const String boolKey = 'testBool'; @@ -506,6 +509,9 @@ void main() { await preferences.clear( const ClearPreferencesParameters(filter: PreferencesFilters()), emptyOptions); + await preferences.clear( + const ClearPreferencesParameters(filter: PreferencesFilters()), + optionsWithSuiteName); return preferences; } @@ -577,6 +583,39 @@ void main() { expect(gotAll[listKey], testList); }); + testWidgets('getPreferences with options', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString, optionsWithSuiteName), + preferences.setBool(boolKey, testBool, emptyOptions), + preferences.setInt(intKey, testInt, optionsWithSuiteName), + preferences.setDouble(doubleKey, testDouble, emptyOptions), + preferences.setStringList(listKey, testList, optionsWithSuiteName) + ]); + + final Map preferencesWithEmptyOptions = + await preferences.getPreferences( + const GetPreferencesParameters(filter: PreferencesFilters()), + emptyOptions, + ); + + final Map preferencesWithSuiteName = + await preferences.getPreferences( + const GetPreferencesParameters(filter: PreferencesFilters()), + optionsWithSuiteName, + ); + + expect(preferencesWithEmptyOptions.length, 2); + expect(preferencesWithSuiteName.length, 3); + + expect(preferencesWithEmptyOptions[boolKey], testBool); + expect(preferencesWithEmptyOptions[doubleKey], testDouble); + + expect(preferencesWithSuiteName[stringKey], testString); + expect(preferencesWithSuiteName[intKey], testInt); + expect(preferencesWithSuiteName[listKey], testList); + }); + testWidgets('getPreferences with filter', (WidgetTester _) async { final SharedPreferencesAsyncPlatform preferences = await getPreferences(); await Future.wait(>[ @@ -622,6 +661,37 @@ void main() { expect(keys, contains(listKey)); }); + testWidgets('getKeys with options', (WidgetTester _) async { + final SharedPreferencesAsyncPlatform preferences = await getPreferences(); + await Future.wait(>[ + preferences.setString(stringKey, testString, optionsWithSuiteName), + preferences.setBool(boolKey, testBool, emptyOptions), + preferences.setInt(intKey, testInt, optionsWithSuiteName), + preferences.setDouble(doubleKey, testDouble, emptyOptions), + preferences.setStringList(listKey, testList, optionsWithSuiteName) + ]); + + final Set keysWithEmptyOptions = await preferences.getKeys( + const GetPreferencesParameters(filter: PreferencesFilters()), + emptyOptions, + ); + + final Set keysWithSuiteName = await preferences.getKeys( + const GetPreferencesParameters(filter: PreferencesFilters()), + optionsWithSuiteName, + ); + + expect(keysWithEmptyOptions.length, 2); + expect(keysWithSuiteName.length, 3); + + expect(keysWithEmptyOptions, contains(boolKey)); + expect(keysWithEmptyOptions, contains(doubleKey)); + + expect(keysWithSuiteName, contains(stringKey)); + expect(keysWithSuiteName, contains(intKey)); + expect(keysWithSuiteName, contains(listKey)); + }); + testWidgets('getKeys with filter', (WidgetTester _) async { final SharedPreferencesAsyncPlatform preferences = await getPreferences(); await Future.wait(>[ diff --git a/packages/shared_preferences/shared_preferences_foundation/pubspec.yaml b/packages/shared_preferences/shared_preferences_foundation/pubspec.yaml index 50b20675b808..f873bb6d8e70 100644 --- a/packages/shared_preferences/shared_preferences_foundation/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_foundation/pubspec.yaml @@ -2,7 +2,7 @@ name: shared_preferences_foundation description: iOS and macOS implementation of the shared_preferences plugin. repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences_foundation issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22 -version: 2.5.1 +version: 2.5.2 environment: sdk: ^3.3.0