[shared_preferences] upgraded ios to using pigeon (#4732)
diff --git a/packages/shared_preferences/shared_preferences_ios/CHANGELOG.md b/packages/shared_preferences/shared_preferences_ios/CHANGELOG.md
index b2a9f14..a5cc1d3 100644
--- a/packages/shared_preferences/shared_preferences_ios/CHANGELOG.md
+++ b/packages/shared_preferences/shared_preferences_ios/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.1.0
+
+* Upgrades to using Pigeon.
+
## 2.0.10
* Switches to an in-package method channel implementation.
diff --git a/packages/shared_preferences/shared_preferences_ios/ios/Classes/FLTSharedPreferencesPlugin.m b/packages/shared_preferences/shared_preferences_ios/ios/Classes/FLTSharedPreferencesPlugin.m
index 4d49e3b..bb11da2 100644
--- a/packages/shared_preferences/shared_preferences_ios/ios/Classes/FLTSharedPreferencesPlugin.m
+++ b/packages/shared_preferences/shared_preferences_ios/ios/Classes/FLTSharedPreferencesPlugin.m
@@ -3,68 +3,7 @@
// found in the LICENSE file.
#import "FLTSharedPreferencesPlugin.h"
-
-static NSString *const CHANNEL_NAME = @"plugins.flutter.io/shared_preferences_ios";
-
-@implementation FLTSharedPreferencesPlugin
-
-+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
- FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:CHANNEL_NAME
- binaryMessenger:registrar.messenger];
- [channel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) {
- NSString *method = [call method];
- NSDictionary *arguments = [call arguments];
-
- if ([method isEqualToString:@"getAll"]) {
- result(getAllPrefs());
- } else if ([method isEqualToString:@"setBool"]) {
- NSString *key = arguments[@"key"];
- NSNumber *value = arguments[@"value"];
- [[NSUserDefaults standardUserDefaults] setBool:value.boolValue forKey:key];
- result(@YES);
- } else if ([method isEqualToString:@"setInt"]) {
- NSString *key = arguments[@"key"];
- NSNumber *value = arguments[@"value"];
- // int type in Dart can come to native side in a variety of forms
- // It is best to store it as is and send it back when needed.
- // Platform channel will handle the conversion.
- [[NSUserDefaults standardUserDefaults] setValue:value forKey:key];
- result(@YES);
- } else if ([method isEqualToString:@"setDouble"]) {
- NSString *key = arguments[@"key"];
- NSNumber *value = arguments[@"value"];
- [[NSUserDefaults standardUserDefaults] setDouble:value.doubleValue forKey:key];
- result(@YES);
- } else if ([method isEqualToString:@"setString"]) {
- NSString *key = arguments[@"key"];
- NSString *value = arguments[@"value"];
- [[NSUserDefaults standardUserDefaults] setValue:value forKey:key];
- result(@YES);
- } else if ([method isEqualToString:@"setStringList"]) {
- NSString *key = arguments[@"key"];
- NSArray *value = arguments[@"value"];
- [[NSUserDefaults standardUserDefaults] setValue:value forKey:key];
- result(@YES);
- } else if ([method isEqualToString:@"commit"]) {
- // synchronize is deprecated.
- // "this method is unnecessary and shouldn't be used."
- result(@YES);
- } else if ([method isEqualToString:@"remove"]) {
- [[NSUserDefaults standardUserDefaults] removeObjectForKey:arguments[@"key"]];
- result(@YES);
- } else if ([method isEqualToString:@"clear"]) {
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- for (NSString *key in getAllPrefs()) {
- [defaults removeObjectForKey:key];
- }
- result(@YES);
- } else {
- result(FlutterMethodNotImplemented);
- }
- }];
-}
-
-#pragma mark - Private
+#import "messages.g.h"
static NSMutableDictionary *getAllPrefs() {
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
@@ -80,4 +19,50 @@
return filteredPrefs;
}
+@interface FLTSharedPreferencesPlugin () <UserDefaultsApi>
+@end
+
+@implementation FLTSharedPreferencesPlugin
+
++ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar> *)registrar {
+ FLTSharedPreferencesPlugin *plugin = [[FLTSharedPreferencesPlugin alloc] init];
+ UserDefaultsApiSetup(registrar.messenger, plugin);
+}
+
+// Must not return nil unless "error" is set.
+- (nullable NSDictionary<NSString *, id> *)getAllWithError:
+ (FlutterError *_Nullable __autoreleasing *_Nonnull)error {
+ return getAllPrefs();
+}
+
+- (void)clearWithError:(FlutterError *_Nullable __autoreleasing *_Nonnull)error {
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+ for (NSString *key in getAllPrefs()) {
+ [defaults removeObjectForKey:key];
+ }
+}
+
+- (void)removeKey:(nonnull NSString *)key
+ error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error {
+ [[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
+}
+
+- (void)setBoolKey:(nonnull NSString *)key
+ value:(nonnull NSNumber *)value
+ error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error {
+ [[NSUserDefaults standardUserDefaults] setBool:value.boolValue forKey:key];
+}
+
+- (void)setDoubleKey:(nonnull NSString *)key
+ value:(nonnull NSNumber *)value
+ error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error {
+ [[NSUserDefaults standardUserDefaults] setDouble:value.doubleValue forKey:key];
+}
+
+- (void)setValueKey:(nonnull NSString *)key
+ value:(nonnull NSString *)value
+ error:(FlutterError *_Nullable __autoreleasing *_Nonnull)error {
+ [[NSUserDefaults standardUserDefaults] setValue:value forKey:key];
+}
+
@end
diff --git a/packages/shared_preferences/shared_preferences_ios/ios/Classes/messages.g.h b/packages/shared_preferences/shared_preferences_ios/ios/Classes/messages.g.h
new file mode 100644
index 0000000..5924023
--- /dev/null
+++ b/packages/shared_preferences/shared_preferences_ios/ios/Classes/messages.g.h
@@ -0,0 +1,33 @@
+// 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.
+// Autogenerated from Pigeon (v1.0.16), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+#import <Foundation/Foundation.h>
+@protocol FlutterBinaryMessenger;
+@protocol FlutterMessageCodec;
+@class FlutterError;
+@class FlutterStandardTypedData;
+
+NS_ASSUME_NONNULL_BEGIN
+
+/// The codec used by UserDefaultsApi.
+NSObject<FlutterMessageCodec> *UserDefaultsApiGetCodec(void);
+
+@protocol UserDefaultsApi
+- (void)removeKey:(NSString *)key error:(FlutterError *_Nullable *_Nonnull)error;
+- (void)setBoolKey:(NSString *)key
+ value:(NSNumber *)value
+ error:(FlutterError *_Nullable *_Nonnull)error;
+- (void)setDoubleKey:(NSString *)key
+ value:(NSNumber *)value
+ error:(FlutterError *_Nullable *_Nonnull)error;
+- (void)setValueKey:(NSString *)key value:(id)value error:(FlutterError *_Nullable *_Nonnull)error;
+- (nullable NSDictionary<NSString *, id> *)getAllWithError:(FlutterError *_Nullable *_Nonnull)error;
+- (void)clearWithError:(FlutterError *_Nullable *_Nonnull)error;
+@end
+
+extern void UserDefaultsApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
+ NSObject<UserDefaultsApi> *_Nullable api);
+
+NS_ASSUME_NONNULL_END
diff --git a/packages/shared_preferences/shared_preferences_ios/ios/Classes/messages.g.m b/packages/shared_preferences/shared_preferences_ios/ios/Classes/messages.g.m
new file mode 100644
index 0000000..ea8c45c
--- /dev/null
+++ b/packages/shared_preferences/shared_preferences_ios/ios/Classes/messages.g.m
@@ -0,0 +1,178 @@
+// 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.
+// Autogenerated from Pigeon (v1.0.16), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+#import "messages.g.h"
+#import <Flutter/Flutter.h>
+
+#if !__has_feature(objc_arc)
+#error File requires ARC to be enabled.
+#endif
+
+static NSDictionary<NSString *, id> *wrapResult(id result, FlutterError *error) {
+ NSDictionary *errorDict = (NSDictionary *)[NSNull null];
+ if (error) {
+ errorDict = @{
+ @"code" : (error.code ? error.code : [NSNull null]),
+ @"message" : (error.message ? error.message : [NSNull null]),
+ @"details" : (error.details ? error.details : [NSNull null]),
+ };
+ }
+ return @{
+ @"result" : (result ? result : [NSNull null]),
+ @"error" : errorDict,
+ };
+}
+
+@interface UserDefaultsApiCodecReader : FlutterStandardReader
+@end
+@implementation UserDefaultsApiCodecReader
+@end
+
+@interface UserDefaultsApiCodecWriter : FlutterStandardWriter
+@end
+@implementation UserDefaultsApiCodecWriter
+@end
+
+@interface UserDefaultsApiCodecReaderWriter : FlutterStandardReaderWriter
+@end
+@implementation UserDefaultsApiCodecReaderWriter
+- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
+ return [[UserDefaultsApiCodecWriter alloc] initWithData:data];
+}
+- (FlutterStandardReader *)readerWithData:(NSData *)data {
+ return [[UserDefaultsApiCodecReader alloc] initWithData:data];
+}
+@end
+
+NSObject<FlutterMessageCodec> *UserDefaultsApiGetCodec() {
+ static dispatch_once_t s_pred = 0;
+ static FlutterStandardMessageCodec *s_sharedObject = nil;
+ dispatch_once(&s_pred, ^{
+ UserDefaultsApiCodecReaderWriter *readerWriter =
+ [[UserDefaultsApiCodecReaderWriter alloc] init];
+ s_sharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
+ });
+ return s_sharedObject;
+}
+
+void UserDefaultsApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
+ NSObject<UserDefaultsApi> *api) {
+ {
+ FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+ messageChannelWithName:@"dev.flutter.pigeon.UserDefaultsApi.remove"
+ binaryMessenger:binaryMessenger
+ codec:UserDefaultsApiGetCodec()];
+ if (api) {
+ NSCAssert([api respondsToSelector:@selector(removeKey:error:)],
+ @"UserDefaultsApi api (%@) doesn't respond to @selector(removeKey:error:)", api);
+ [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+ NSArray *args = message;
+ NSString *arg_key = args[0];
+ FlutterError *error;
+ [api removeKey:arg_key error:&error];
+ callback(wrapResult(nil, error));
+ }];
+ } else {
+ [channel setMessageHandler:nil];
+ }
+ }
+ {
+ FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+ messageChannelWithName:@"dev.flutter.pigeon.UserDefaultsApi.setBool"
+ binaryMessenger:binaryMessenger
+ codec:UserDefaultsApiGetCodec()];
+ if (api) {
+ NSCAssert([api respondsToSelector:@selector(setBoolKey:value:error:)],
+ @"UserDefaultsApi api (%@) doesn't respond to @selector(setBoolKey:value:error:)",
+ api);
+ [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+ NSArray *args = message;
+ NSString *arg_key = args[0];
+ NSNumber *arg_value = args[1];
+ FlutterError *error;
+ [api setBoolKey:arg_key value:arg_value error:&error];
+ callback(wrapResult(nil, error));
+ }];
+ } else {
+ [channel setMessageHandler:nil];
+ }
+ }
+ {
+ FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+ messageChannelWithName:@"dev.flutter.pigeon.UserDefaultsApi.setDouble"
+ binaryMessenger:binaryMessenger
+ codec:UserDefaultsApiGetCodec()];
+ if (api) {
+ NSCAssert([api respondsToSelector:@selector(setDoubleKey:value:error:)],
+ @"UserDefaultsApi api (%@) doesn't respond to @selector(setDoubleKey:value:error:)",
+ api);
+ [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+ NSArray *args = message;
+ NSString *arg_key = args[0];
+ NSNumber *arg_value = args[1];
+ FlutterError *error;
+ [api setDoubleKey:arg_key value:arg_value error:&error];
+ callback(wrapResult(nil, error));
+ }];
+ } else {
+ [channel setMessageHandler:nil];
+ }
+ }
+ {
+ FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+ messageChannelWithName:@"dev.flutter.pigeon.UserDefaultsApi.setValue"
+ binaryMessenger:binaryMessenger
+ codec:UserDefaultsApiGetCodec()];
+ if (api) {
+ NSCAssert([api respondsToSelector:@selector(setValueKey:value:error:)],
+ @"UserDefaultsApi api (%@) doesn't respond to @selector(setValueKey:value:error:)",
+ api);
+ [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+ NSArray *args = message;
+ NSString *arg_key = args[0];
+ id arg_value = args[1];
+ FlutterError *error;
+ [api setValueKey:arg_key value:arg_value error:&error];
+ callback(wrapResult(nil, error));
+ }];
+ } else {
+ [channel setMessageHandler:nil];
+ }
+ }
+ {
+ FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+ messageChannelWithName:@"dev.flutter.pigeon.UserDefaultsApi.getAll"
+ binaryMessenger:binaryMessenger
+ codec:UserDefaultsApiGetCodec()];
+ if (api) {
+ NSCAssert([api respondsToSelector:@selector(getAllWithError:)],
+ @"UserDefaultsApi api (%@) doesn't respond to @selector(getAllWithError:)", api);
+ [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+ FlutterError *error;
+ NSDictionary<NSString *, id> *output = [api getAllWithError:&error];
+ callback(wrapResult(output, error));
+ }];
+ } else {
+ [channel setMessageHandler:nil];
+ }
+ }
+ {
+ FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
+ messageChannelWithName:@"dev.flutter.pigeon.UserDefaultsApi.clear"
+ binaryMessenger:binaryMessenger
+ codec:UserDefaultsApiGetCodec()];
+ if (api) {
+ NSCAssert([api respondsToSelector:@selector(clearWithError:)],
+ @"UserDefaultsApi api (%@) doesn't respond to @selector(clearWithError:)", api);
+ [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
+ FlutterError *error;
+ [api clearWithError:&error];
+ callback(wrapResult(nil, error));
+ }];
+ } else {
+ [channel setMessageHandler:nil];
+ }
+ }
+}
diff --git a/packages/shared_preferences/shared_preferences_ios/lib/messages.g.dart b/packages/shared_preferences/shared_preferences_ios/lib/messages.g.dart
new file mode 100644
index 0000000..0e76291
--- /dev/null
+++ b/packages/shared_preferences/shared_preferences_ios/lib/messages.g.dart
@@ -0,0 +1,179 @@
+// 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.
+// Autogenerated from Pigeon (v1.0.16), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name
+// @dart = 2.12
+import 'dart:async';
+import 'dart:typed_data' show Uint8List, Int32List, Int64List, Float64List;
+
+import 'package:flutter/foundation.dart' show WriteBuffer, ReadBuffer;
+import 'package:flutter/services.dart';
+
+class _UserDefaultsApiCodec extends StandardMessageCodec {
+ const _UserDefaultsApiCodec();
+}
+
+class UserDefaultsApi {
+ /// Constructor for [UserDefaultsApi]. The [binaryMessenger] named argument is
+ /// available for dependency injection. If it is left null, the default
+ /// BinaryMessenger will be used which routes to the host platform.
+ UserDefaultsApi({BinaryMessenger? binaryMessenger})
+ : _binaryMessenger = binaryMessenger;
+
+ final BinaryMessenger? _binaryMessenger;
+
+ static const MessageCodec<Object?> codec = _UserDefaultsApiCodec();
+
+ Future<void> remove(String arg_key) async {
+ final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.UserDefaultsApi.remove', codec,
+ binaryMessenger: _binaryMessenger);
+ final Map<Object?, Object?>? replyMap =
+ await channel.send(<Object>[arg_key]) as Map<Object?, Object?>?;
+ if (replyMap == null) {
+ throw PlatformException(
+ code: 'channel-error',
+ message: 'Unable to establish connection on channel.',
+ details: null,
+ );
+ } else if (replyMap['error'] != null) {
+ final Map<Object?, Object?> error =
+ (replyMap['error'] as Map<Object?, Object?>?)!;
+ throw PlatformException(
+ code: (error['code'] as String?)!,
+ message: error['message'] as String?,
+ details: error['details'],
+ );
+ } else {
+ return;
+ }
+ }
+
+ Future<void> setBool(String arg_key, bool arg_value) async {
+ final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.UserDefaultsApi.setBool', codec,
+ binaryMessenger: _binaryMessenger);
+ final Map<Object?, Object?>? replyMap = await channel
+ .send(<Object>[arg_key, arg_value]) as Map<Object?, Object?>?;
+ if (replyMap == null) {
+ throw PlatformException(
+ code: 'channel-error',
+ message: 'Unable to establish connection on channel.',
+ details: null,
+ );
+ } else if (replyMap['error'] != null) {
+ final Map<Object?, Object?> error =
+ (replyMap['error'] as Map<Object?, Object?>?)!;
+ throw PlatformException(
+ code: (error['code'] as String?)!,
+ message: error['message'] as String?,
+ details: error['details'],
+ );
+ } else {
+ return;
+ }
+ }
+
+ Future<void> setDouble(String arg_key, double arg_value) async {
+ final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.UserDefaultsApi.setDouble', codec,
+ binaryMessenger: _binaryMessenger);
+ final Map<Object?, Object?>? replyMap = await channel
+ .send(<Object>[arg_key, arg_value]) as Map<Object?, Object?>?;
+ if (replyMap == null) {
+ throw PlatformException(
+ code: 'channel-error',
+ message: 'Unable to establish connection on channel.',
+ details: null,
+ );
+ } else if (replyMap['error'] != null) {
+ final Map<Object?, Object?> error =
+ (replyMap['error'] as Map<Object?, Object?>?)!;
+ throw PlatformException(
+ code: (error['code'] as String?)!,
+ message: error['message'] as String?,
+ details: error['details'],
+ );
+ } else {
+ return;
+ }
+ }
+
+ Future<void> setValue(String arg_key, Object arg_value) async {
+ final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.UserDefaultsApi.setValue', codec,
+ binaryMessenger: _binaryMessenger);
+ final Map<Object?, Object?>? replyMap = await channel
+ .send(<Object>[arg_key, arg_value]) as Map<Object?, Object?>?;
+ if (replyMap == null) {
+ throw PlatformException(
+ code: 'channel-error',
+ message: 'Unable to establish connection on channel.',
+ details: null,
+ );
+ } else if (replyMap['error'] != null) {
+ final Map<Object?, Object?> error =
+ (replyMap['error'] as Map<Object?, Object?>?)!;
+ throw PlatformException(
+ code: (error['code'] as String?)!,
+ message: error['message'] as String?,
+ details: error['details'],
+ );
+ } else {
+ return;
+ }
+ }
+
+ Future<Map<String?, Object?>> getAll() async {
+ final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.UserDefaultsApi.getAll', codec,
+ binaryMessenger: _binaryMessenger);
+ final Map<Object?, Object?>? replyMap =
+ await channel.send(null) as Map<Object?, Object?>?;
+ if (replyMap == null) {
+ throw PlatformException(
+ code: 'channel-error',
+ message: 'Unable to establish connection on channel.',
+ details: null,
+ );
+ } else if (replyMap['error'] != null) {
+ final Map<Object?, Object?> error =
+ (replyMap['error'] as Map<Object?, Object?>?)!;
+ throw PlatformException(
+ code: (error['code'] as String?)!,
+ message: error['message'] as String?,
+ details: error['details'],
+ );
+ } else {
+ return (replyMap['result'] as Map<Object?, Object?>?)!
+ .cast<String?, Object?>();
+ }
+ }
+
+ Future<void> clear() async {
+ final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.UserDefaultsApi.clear', codec,
+ binaryMessenger: _binaryMessenger);
+ final Map<Object?, Object?>? replyMap =
+ await channel.send(null) as Map<Object?, Object?>?;
+ if (replyMap == null) {
+ throw PlatformException(
+ code: 'channel-error',
+ message: 'Unable to establish connection on channel.',
+ details: null,
+ );
+ } else if (replyMap['error'] != null) {
+ final Map<Object?, Object?> error =
+ (replyMap['error'] as Map<Object?, Object?>?)!;
+ throw PlatformException(
+ code: (error['code'] as String?)!,
+ message: error['message'] as String?,
+ details: error['details'],
+ );
+ } else {
+ return;
+ }
+ }
+}
diff --git a/packages/shared_preferences/shared_preferences_ios/lib/shared_preferences_ios.dart b/packages/shared_preferences/shared_preferences_ios/lib/shared_preferences_ios.dart
index 15f1e2f..1063884 100644
--- a/packages/shared_preferences/shared_preferences_ios/lib/shared_preferences_ios.dart
+++ b/packages/shared_preferences/shared_preferences_ios/lib/shared_preferences_ios.dart
@@ -2,52 +2,65 @@
// 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/services.dart';
import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart';
+import 'messages.g.dart';
-const MethodChannel _kChannel =
- MethodChannel('plugins.flutter.io/shared_preferences_ios');
+typedef _Setter = Future<void> Function(String key, Object value);
-/// The macOS implementation of [SharedPreferencesStorePlatform].
-///
-/// This class implements the `package:shared_preferences` functionality for iOS.
+/// iOS implementation of shared_preferences.
class SharedPreferencesIOS extends SharedPreferencesStorePlatform {
- /// Registers this class as the default instance of [SharedPreferencesStorePlatform].
+ final UserDefaultsApi _api = UserDefaultsApi();
+ late final Map<String, _Setter> _setters = <String, _Setter>{
+ 'Bool': (String key, Object value) {
+ return _api.setBool(key, value as bool);
+ },
+ 'Double': (String key, Object value) {
+ return _api.setDouble(key, value as double);
+ },
+ 'Int': (String key, Object value) {
+ return _api.setValue(key, value as int);
+ },
+ 'String': (String key, Object value) {
+ return _api.setValue(key, value as String);
+ },
+ 'StringList': (String key, Object value) {
+ return _api.setValue(key, value as List<String?>);
+ },
+ };
+
+ /// Registers this class as the default instance of [PathProviderPlatform].
static void registerWith() {
SharedPreferencesStorePlatform.instance = SharedPreferencesIOS();
}
@override
- Future<bool> remove(String key) async {
- return (await _kChannel.invokeMethod<bool>(
- 'remove',
- <String, dynamic>{'key': key},
- ))!;
- }
-
- @override
- Future<bool> setValue(String valueType, String key, Object value) async {
- return (await _kChannel.invokeMethod<bool>(
- 'set$valueType',
- <String, dynamic>{'key': key, 'value': value},
- ))!;
- }
-
- @override
Future<bool> clear() async {
- return (await _kChannel.invokeMethod<bool>('clear'))!;
+ await _api.clear();
+ return true;
}
@override
Future<Map<String, Object>> getAll() async {
- final Map<String, Object>? preferences =
- await _kChannel.invokeMapMethod<String, Object>('getAll');
+ final Map<String?, Object?> result = await _api.getAll();
+ return result.cast<String, Object>();
+ }
- if (preferences == null) {
- return <String, Object>{};
+ @override
+ Future<bool> remove(String key) async {
+ await _api.remove(key);
+ return true;
+ }
+
+ @override
+ Future<bool> setValue(String valueType, String key, Object value) async {
+ final _Setter? setter = _setters[valueType];
+ if (setter == null) {
+ throw PlatformException(
+ code: 'InvalidOperation',
+ message: '"$valueType" is not a supported type.');
}
- return preferences;
+ await setter(key, value);
+ return true;
}
}
diff --git a/packages/shared_preferences/shared_preferences_ios/pigeons/copyright_header.txt b/packages/shared_preferences/shared_preferences_ios/pigeons/copyright_header.txt
new file mode 100644
index 0000000..fb682b1
--- /dev/null
+++ b/packages/shared_preferences/shared_preferences_ios/pigeons/copyright_header.txt
@@ -0,0 +1,3 @@
+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.
\ No newline at end of file
diff --git a/packages/shared_preferences/shared_preferences_ios/pigeons/messages.dart b/packages/shared_preferences/shared_preferences_ios/pigeons/messages.dart
new file mode 100644
index 0000000..6b5648f
--- /dev/null
+++ b/packages/shared_preferences/shared_preferences_ios/pigeons/messages.dart
@@ -0,0 +1,22 @@
+// 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 'package:pigeon/pigeon.dart';
+
+@ConfigurePigeon(PigeonOptions(
+ dartOut: 'lib/messages.g.dart',
+ dartTestOut: 'test/messages.g.dart',
+ objcHeaderOut: 'ios/Classes/messages.g.h',
+ objcSourceOut: 'ios/Classes/messages.g.m',
+ copyrightHeader: 'pigeons/copyright_header.txt',
+))
+@HostApi(dartHostTestHandler: 'TestUserDefaultsApi')
+abstract class UserDefaultsApi {
+ void remove(String key);
+ void setBool(String key, bool value);
+ void setDouble(String key, double value);
+ void setValue(String key, Object value);
+ Map<String?, Object?> getAll();
+ void clear();
+}
diff --git a/packages/shared_preferences/shared_preferences_ios/pubspec.yaml b/packages/shared_preferences/shared_preferences_ios/pubspec.yaml
index 68ab035..33bf5ba 100644
--- a/packages/shared_preferences/shared_preferences_ios/pubspec.yaml
+++ b/packages/shared_preferences/shared_preferences_ios/pubspec.yaml
@@ -2,7 +2,7 @@
description: iOS implementation of the shared_preferences plugin
repository: https://github.com/flutter/plugins/tree/main/packages/shared_preferences/shared_preferences_ios
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22
-version: 2.0.10
+version: 2.1.0
environment:
sdk: ">=2.14.0 <3.0.0"
@@ -13,8 +13,8 @@
implements: shared_preferences
platforms:
ios:
- pluginClass: FLTSharedPreferencesPlugin
dartPluginClass: SharedPreferencesIOS
+ pluginClass: FLTSharedPreferencesPlugin
dependencies:
flutter:
@@ -24,3 +24,4 @@
dev_dependencies:
flutter_test:
sdk: flutter
+ pigeon: ^1.0.16
diff --git a/packages/shared_preferences/shared_preferences_ios/test/messages.g.dart b/packages/shared_preferences/shared_preferences_ios/test/messages.g.dart
new file mode 100644
index 0000000..12fbc06
--- /dev/null
+++ b/packages/shared_preferences/shared_preferences_ios/test/messages.g.dart
@@ -0,0 +1,145 @@
+// 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.
+// Autogenerated from Pigeon (v1.0.16), do not edit directly.
+// See also: https://pub.dev/packages/pigeon
+// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import
+// @dart = 2.12
+import 'dart:async';
+import 'dart:typed_data' show Uint8List, Int32List, Int64List, Float64List;
+import 'package:flutter/foundation.dart' show WriteBuffer, ReadBuffer;
+import 'package:flutter/services.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+import 'package:shared_preferences_ios/messages.g.dart';
+
+class _TestUserDefaultsApiCodec extends StandardMessageCodec {
+ const _TestUserDefaultsApiCodec();
+}
+
+abstract class TestUserDefaultsApi {
+ static const MessageCodec<Object?> codec = _TestUserDefaultsApiCodec();
+
+ void remove(String key);
+ void setBool(String key, bool value);
+ void setDouble(String key, double value);
+ void setValue(String key, Object value);
+ Map<String?, Object?> getAll();
+ void clear();
+ static void setup(TestUserDefaultsApi? api,
+ {BinaryMessenger? binaryMessenger}) {
+ {
+ final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.UserDefaultsApi.remove', codec,
+ binaryMessenger: binaryMessenger);
+ if (api == null) {
+ channel.setMockMessageHandler(null);
+ } else {
+ channel.setMockMessageHandler((Object? message) async {
+ assert(message != null,
+ 'Argument for dev.flutter.pigeon.UserDefaultsApi.remove was null.');
+ final List<Object?> args = (message as List<Object?>?)!;
+ final String? arg_key = (args[0] as String?);
+ assert(arg_key != null,
+ 'Argument for dev.flutter.pigeon.UserDefaultsApi.remove was null, expected non-null String.');
+ api.remove(arg_key!);
+ return <Object?, Object?>{};
+ });
+ }
+ }
+ {
+ final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.UserDefaultsApi.setBool', codec,
+ binaryMessenger: binaryMessenger);
+ if (api == null) {
+ channel.setMockMessageHandler(null);
+ } else {
+ channel.setMockMessageHandler((Object? message) async {
+ assert(message != null,
+ 'Argument for dev.flutter.pigeon.UserDefaultsApi.setBool was null.');
+ final List<Object?> args = (message as List<Object?>?)!;
+ final String? arg_key = (args[0] as String?);
+ assert(arg_key != null,
+ 'Argument for dev.flutter.pigeon.UserDefaultsApi.setBool was null, expected non-null String.');
+ final bool? arg_value = (args[1] as bool?);
+ assert(arg_value != null,
+ 'Argument for dev.flutter.pigeon.UserDefaultsApi.setBool was null, expected non-null bool.');
+ api.setBool(arg_key!, arg_value!);
+ return <Object?, Object?>{};
+ });
+ }
+ }
+ {
+ final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.UserDefaultsApi.setDouble', codec,
+ binaryMessenger: binaryMessenger);
+ if (api == null) {
+ channel.setMockMessageHandler(null);
+ } else {
+ channel.setMockMessageHandler((Object? message) async {
+ assert(message != null,
+ 'Argument for dev.flutter.pigeon.UserDefaultsApi.setDouble was null.');
+ final List<Object?> args = (message as List<Object?>?)!;
+ final String? arg_key = (args[0] as String?);
+ assert(arg_key != null,
+ 'Argument for dev.flutter.pigeon.UserDefaultsApi.setDouble was null, expected non-null String.');
+ final double? arg_value = (args[1] as double?);
+ assert(arg_value != null,
+ 'Argument for dev.flutter.pigeon.UserDefaultsApi.setDouble was null, expected non-null double.');
+ api.setDouble(arg_key!, arg_value!);
+ return <Object?, Object?>{};
+ });
+ }
+ }
+ {
+ final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.UserDefaultsApi.setValue', codec,
+ binaryMessenger: binaryMessenger);
+ if (api == null) {
+ channel.setMockMessageHandler(null);
+ } else {
+ channel.setMockMessageHandler((Object? message) async {
+ assert(message != null,
+ 'Argument for dev.flutter.pigeon.UserDefaultsApi.setValue was null.');
+ final List<Object?> args = (message as List<Object?>?)!;
+ final String? arg_key = (args[0] as String?);
+ assert(arg_key != null,
+ 'Argument for dev.flutter.pigeon.UserDefaultsApi.setValue was null, expected non-null String.');
+ final Object? arg_value = (args[1] as Object?);
+ assert(arg_value != null,
+ 'Argument for dev.flutter.pigeon.UserDefaultsApi.setValue was null, expected non-null Object.');
+ api.setValue(arg_key!, arg_value!);
+ return <Object?, Object?>{};
+ });
+ }
+ }
+ {
+ final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.UserDefaultsApi.getAll', codec,
+ binaryMessenger: binaryMessenger);
+ if (api == null) {
+ channel.setMockMessageHandler(null);
+ } else {
+ channel.setMockMessageHandler((Object? message) async {
+ // ignore message
+ final Map<String?, Object?> output = api.getAll();
+ return <Object?, Object?>{'result': output};
+ });
+ }
+ }
+ {
+ final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
+ 'dev.flutter.pigeon.UserDefaultsApi.clear', codec,
+ binaryMessenger: binaryMessenger);
+ if (api == null) {
+ channel.setMockMessageHandler(null);
+ } else {
+ channel.setMockMessageHandler((Object? message) async {
+ // ignore message
+ api.clear();
+ return <Object?, Object?>{};
+ });
+ }
+ }
+ }
+}
diff --git a/packages/shared_preferences/shared_preferences_ios/test/shared_preferences_ios_test.dart b/packages/shared_preferences/shared_preferences_ios/test/shared_preferences_ios_test.dart
index 8eb23f2..efafb23 100644
--- a/packages/shared_preferences/shared_preferences_ios/test/shared_preferences_ios_test.dart
+++ b/packages/shared_preferences/shared_preferences_ios/test/shared_preferences_ios_test.dart
@@ -5,113 +5,101 @@
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences_ios/shared_preferences_ios.dart';
-import 'package:shared_preferences_platform_interface/method_channel_shared_preferences.dart';
import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart';
+import 'messages.g.dart';
+
+class _MockSharedPreferencesApi implements TestUserDefaultsApi {
+ final Map<String, Object> items = <String, Object>{};
+
+ @override
+ Map<String?, Object?> getAll() {
+ return items;
+ }
+
+ @override
+ void remove(String key) {
+ items.remove(key);
+ }
+
+ @override
+ void setBool(String key, bool value) {
+ items[key] = value;
+ }
+
+ @override
+ void setDouble(String key, double value) {
+ items[key] = value;
+ }
+
+ @override
+ void setValue(String key, Object value) {
+ items[key] = value;
+ }
+
+ @override
+ void clear() {
+ items.clear();
+ }
+}
+
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
+ _MockSharedPreferencesApi api = _MockSharedPreferencesApi();
+ SharedPreferencesIOS plugin = SharedPreferencesIOS();
- group(MethodChannelSharedPreferencesStore, () {
- const MethodChannel channel = MethodChannel(
- 'plugins.flutter.io/shared_preferences_ios',
- );
+ setUp(() {
+ api = _MockSharedPreferencesApi();
+ TestUserDefaultsApi.setup(api);
+ plugin = SharedPreferencesIOS();
+ });
- const Map<String, Object> kTestValues = <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.
- late InMemorySharedPreferencesStore testData;
+ test('registerWith', () {
+ SharedPreferencesIOS.registerWith();
+ expect(
+ SharedPreferencesStorePlatform.instance, isA<SharedPreferencesIOS>());
+ });
- final List<MethodCall> log = <MethodCall>[];
- late SharedPreferencesStorePlatform store;
+ test('remove', () async {
+ api.items['flutter.hi'] = 'world';
+ expect(await plugin.remove('flutter.hi'), isTrue);
+ expect(api.items.containsKey('flutter.hi'), isFalse);
+ });
- setUp(() async {
- testData = InMemorySharedPreferencesStore.empty();
+ test('clear', () async {
+ api.items['flutter.hi'] = 'world';
+ expect(await plugin.clear(), isTrue);
+ expect(api.items.containsKey('flutter.hi'), isFalse);
+ });
- channel.setMockMethodCallHandler((MethodCall methodCall) async {
- log.add(methodCall);
- if (methodCall.method == 'getAll') {
- return await testData.getAll();
- }
- if (methodCall.method == 'remove') {
- final String key = methodCall.arguments['key'] as String;
- return await testData.remove(key);
- }
- if (methodCall.method == 'clear') {
- return await testData.clear();
- }
- final RegExp setterRegExp = RegExp(r'set(.*)');
- final Match? match = setterRegExp.matchAsPrefix(methodCall.method);
- if (match?.groupCount == 1) {
- final String valueType = match!.group(1)!;
- final String key = methodCall.arguments['key'] as String;
- final Object value = methodCall.arguments['value'] as Object;
- return await testData.setValue(valueType, key, value);
- }
- fail('Unexpected method call: ${methodCall.method}');
- });
- log.clear();
- });
+ test('getAll', () async {
+ api.items['flutter.hi'] = 'world';
+ api.items['flutter.bye'] = 'dust';
+ final Map<String?, Object?> all = await plugin.getAll();
+ expect(all.length, 2);
+ expect(all['flutter.hi'], api.items['flutter.hi']);
+ expect(all['flutter.bye'], api.items['flutter.bye']);
+ });
- test('registered instance', () {
- SharedPreferencesIOS.registerWith();
- expect(
- SharedPreferencesStorePlatform.instance, isA<SharedPreferencesIOS>());
- });
+ test('setValue', () async {
+ expect(await plugin.setValue('Bool', 'flutter.Bool', true), isTrue);
+ expect(api.items['flutter.Bool'], true);
+ expect(await plugin.setValue('Double', 'flutter.Double', 1.5), isTrue);
+ expect(api.items['flutter.Double'], 1.5);
+ expect(await plugin.setValue('Int', 'flutter.Int', 12), isTrue);
+ expect(api.items['flutter.Int'], 12);
+ expect(await plugin.setValue('String', 'flutter.String', 'hi'), isTrue);
+ expect(api.items['flutter.String'], 'hi');
+ expect(
+ await plugin
+ .setValue('StringList', 'flutter.StringList', <String>['hi']),
+ isTrue);
+ expect(api.items['flutter.StringList'], <String>['hi']);
+ });
- test('getAll', () async {
- store = SharedPreferencesIOS();
- testData = InMemorySharedPreferencesStore.withData(kTestValues);
- expect(await store.getAll(), kTestValues);
- expect(log.single.method, 'getAll');
- });
-
- test('remove', () async {
- store = SharedPreferencesIOS();
- testData = InMemorySharedPreferencesStore.withData(kTestValues);
- expect(await store.remove('flutter.String'), true);
- expect(await store.remove('flutter.Bool'), true);
- expect(await store.remove('flutter.Int'), true);
- expect(await store.remove('flutter.Double'), true);
- expect(await testData.getAll(), <String, dynamic>{
- 'flutter.StringList': <String>['foo', 'bar'],
- });
-
- expect(log, hasLength(4));
- for (final MethodCall call in log) {
- expect(call.method, 'remove');
- }
- });
-
- test('setValue', () async {
- store = SharedPreferencesIOS();
- expect(await testData.getAll(), isEmpty);
- for (final String key in kTestValues.keys) {
- final Object value = kTestValues[key]!;
- expect(await store.setValue(key.split('.').last, key, value), true);
- }
- expect(await testData.getAll(), kTestValues);
-
- expect(log, hasLength(5));
- expect(log[0].method, 'setString');
- expect(log[1].method, 'setBool');
- expect(log[2].method, 'setInt');
- expect(log[3].method, 'setDouble');
- expect(log[4].method, 'setStringList');
- });
-
- test('clear', () async {
- store = SharedPreferencesIOS();
- testData = InMemorySharedPreferencesStore.withData(kTestValues);
- expect(await testData.getAll(), isNotEmpty);
- expect(await store.clear(), true);
- expect(await testData.getAll(), isEmpty);
- expect(log.single.method, 'clear');
- });
+ test('setValue with unsupported type', () {
+ expect(() async {
+ await plugin.setValue('Map', 'flutter.key', <String, String>{});
+ }, throwsA(isA<PlatformException>()));
});
}