| // 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 'package:flutter/foundation.dart'; |
| import 'package:plugin_platform_interface/plugin_platform_interface.dart'; |
| |
| import 'method_channel_shared_preferences.dart'; |
| import 'types.dart'; |
| |
| /// The interface that implementations of shared_preferences must implement. |
| /// |
| /// Platform implementations should extend this class rather than implement it as `shared_preferences` |
| /// does not consider newly added methods to be breaking changes. Extending this class |
| /// (using `extends`) ensures that the subclass will get the default implementation, while |
| /// platform implementations that `implements` this interface will be broken by newly added |
| /// [SharedPreferencesStorePlatform] methods. |
| abstract class SharedPreferencesStorePlatform extends PlatformInterface { |
| /// Constructs a SharedPreferencesStorePlatform. |
| SharedPreferencesStorePlatform() : super(token: _token); |
| |
| static final Object _token = Object(); |
| |
| /// The default instance of [SharedPreferencesStorePlatform] to use. |
| /// |
| /// Defaults to [MethodChannelSharedPreferencesStore]. |
| static SharedPreferencesStorePlatform get instance => _instance; |
| |
| /// Platform-specific plugins should set this with their own platform-specific |
| /// class that extends [SharedPreferencesStorePlatform] when they register themselves. |
| static set instance(SharedPreferencesStorePlatform instance) { |
| if (!instance.isMock) { |
| PlatformInterface.verify(instance, _token); |
| } |
| _instance = instance; |
| } |
| |
| static SharedPreferencesStorePlatform _instance = |
| MethodChannelSharedPreferencesStore(); |
| |
| /// Only mock implementations should set this to true. |
| /// |
| /// Mockito mocks are implementing this class with `implements` which is forbidden for anything |
| /// other than mocks (see class docs). This property provides a backdoor for mockito mocks to |
| /// skip the verification that the class isn't implemented with `implements`. |
| @visibleForTesting |
| @Deprecated('Use MockPlatformInterfaceMixin instead') |
| bool get isMock => false; |
| |
| /// Removes the value associated with the [key]. |
| Future<bool> remove(String key); |
| |
| /// Stores the [value] associated with the [key]. |
| /// |
| /// The [valueType] must match the type of [value] as follows: |
| /// |
| /// * Value type "Bool" must be passed if the value is of type `bool`. |
| /// * Value type "Double" must be passed if the value is of type `double`. |
| /// * Value type "Int" must be passed if the value is of type `int`. |
| /// * Value type "String" must be passed if the value is of type `String`. |
| /// * Value type "StringList" must be passed if the value is of type `List<String>`. |
| Future<bool> setValue(String valueType, String key, Object value); |
| |
| /// Removes all keys and values in the store where the key starts with 'flutter.'. |
| /// |
| /// This default behavior is for backwards compatibility with older versions of this |
| /// plugin, which did not support custom prefixes, and instead always used the |
| /// prefix 'flutter.'. |
| Future<bool> clear(); |
| |
| /// Removes all keys and values in the store with given [prefix]. |
| @Deprecated('Use clearWithParameters instead') |
| Future<bool> clearWithPrefix(String prefix) { |
| throw UnimplementedError('clearWithPrefix is not implemented.'); |
| } |
| |
| /// Removes all keys and values in the store that match [options]. |
| Future<bool> clearWithParameters(ClearParameters parameters) { |
| throw UnimplementedError('clearWithParameters is not implemented.'); |
| } |
| |
| /// Returns all key/value pairs persisted in this store where the key starts with 'flutter.'. |
| /// |
| /// This default behavior is for backwards compatibility with older versions of this |
| /// plugin, which did not support custom prefixes, and instead always used the |
| /// prefix 'flutter.'. |
| Future<Map<String, Object>> getAll(); |
| |
| /// Returns all key/value pairs persisting in this store that have given [prefix]. |
| @Deprecated('Use getAllWithParameters instead') |
| Future<Map<String, Object>> getAllWithPrefix(String prefix) { |
| throw UnimplementedError('getAllWithPrefix is not implemented.'); |
| } |
| |
| /// Returns all key/value pairs persisting in this store that match [options]. |
| Future<Map<String, Object>> getAllWithParameters( |
| GetAllParameters parameters) { |
| throw UnimplementedError('getAllWithParameters is not implemented.'); |
| } |
| } |
| |
| /// Stores data in memory. |
| /// |
| /// Data does not persist across application restarts. This is useful in unit-tests. |
| class InMemorySharedPreferencesStore extends SharedPreferencesStorePlatform { |
| /// Instantiates an empty in-memory preferences store. |
| InMemorySharedPreferencesStore.empty() : _data = <String, Object>{}; |
| |
| /// Instantiates an in-memory preferences store containing a copy of [data]. |
| InMemorySharedPreferencesStore.withData(Map<String, Object> data) |
| : _data = Map<String, Object>.from(data); |
| |
| final Map<String, Object> _data; |
| static const String _defaultPrefix = 'flutter.'; |
| |
| @override |
| Future<bool> clear() async { |
| return clearWithParameters( |
| ClearParameters( |
| filter: PreferencesFilter(prefix: _defaultPrefix), |
| ), |
| ); |
| } |
| |
| @override |
| Future<bool> clearWithPrefix(String prefix) async { |
| return clearWithParameters( |
| ClearParameters( |
| filter: PreferencesFilter(prefix: prefix), |
| ), |
| ); |
| } |
| |
| @override |
| Future<bool> clearWithParameters(ClearParameters parameters) async { |
| final PreferencesFilter filter = parameters.filter; |
| if (filter.allowList != null) { |
| _data.removeWhere((String key, _) => |
| key.startsWith(filter.prefix) && filter.allowList!.contains(key)); |
| } else { |
| _data.removeWhere((String key, _) => key.startsWith(filter.prefix)); |
| } |
| return true; |
| } |
| |
| @override |
| Future<Map<String, Object>> getAll() async { |
| return getAllWithParameters( |
| GetAllParameters( |
| filter: PreferencesFilter(prefix: _defaultPrefix), |
| ), |
| ); |
| } |
| |
| @override |
| Future<Map<String, Object>> getAllWithPrefix(String prefix) async { |
| return getAllWithParameters( |
| GetAllParameters( |
| filter: PreferencesFilter(prefix: prefix), |
| ), |
| ); |
| } |
| |
| @override |
| Future<Map<String, Object>> getAllWithParameters( |
| GetAllParameters parameters) async { |
| final PreferencesFilter filter = parameters.filter; |
| final Map<String, Object> preferences = Map<String, Object>.from(_data); |
| preferences.removeWhere((String key, _) => |
| !key.startsWith(filter.prefix) || |
| (filter.allowList != null && !filter.allowList!.contains(key))); |
| return preferences; |
| } |
| |
| @override |
| Future<bool> remove(String key) async { |
| _data.remove(key); |
| return true; |
| } |
| |
| @override |
| Future<bool> setValue(String valueType, String key, Object value) async { |
| _data[key] = value; |
| return true; |
| } |
| } |