RCTSettingsManager.mm 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. */
  7. #import <React/RCTSettingsManager.h>
  8. #import <FBReactNativeSpec/FBReactNativeSpec.h>
  9. #import <React/RCTBridge.h>
  10. #import <React/RCTConvert.h>
  11. #import <React/RCTEventDispatcher.h>
  12. #import <React/RCTUtils.h>
  13. #import "RCTSettingsPlugins.h"
  14. @interface RCTSettingsManager() <NativeSettingsManagerSpec>
  15. @end
  16. @implementation RCTSettingsManager
  17. {
  18. BOOL _ignoringUpdates;
  19. NSUserDefaults *_defaults;
  20. }
  21. @synthesize bridge = _bridge;
  22. RCT_EXPORT_MODULE()
  23. + (BOOL)requiresMainQueueSetup
  24. {
  25. return NO;
  26. }
  27. - (instancetype)init
  28. {
  29. return [self initWithUserDefaults:[NSUserDefaults standardUserDefaults]];
  30. }
  31. - (instancetype)initWithUserDefaults:(NSUserDefaults *)defaults
  32. {
  33. if ((self = [super init])) {
  34. _defaults = defaults;
  35. [[NSNotificationCenter defaultCenter] addObserver:self
  36. selector:@selector(userDefaultsDidChange:)
  37. name:NSUserDefaultsDidChangeNotification
  38. object:_defaults];
  39. }
  40. return self;
  41. }
  42. - (facebook::react::ModuleConstants<JS::NativeSettingsManager::Constants>)constantsToExport
  43. {
  44. return (facebook::react::ModuleConstants<JS::NativeSettingsManager::Constants>)[self getConstants];
  45. }
  46. - (facebook::react::ModuleConstants<JS::NativeSettingsManager::Constants>)getConstants
  47. {
  48. return facebook::react::typedConstants<JS::NativeSettingsManager::Constants>({
  49. .settings = RCTJSONClean([_defaults dictionaryRepresentation])
  50. });
  51. }
  52. - (void)userDefaultsDidChange:(NSNotification *)note
  53. {
  54. if (_ignoringUpdates) {
  55. return;
  56. }
  57. #pragma clang diagnostic push
  58. #pragma clang diagnostic ignored "-Wdeprecated-declarations"
  59. [_bridge.eventDispatcher
  60. sendDeviceEventWithName:@"settingsUpdated"
  61. body:RCTJSONClean([_defaults dictionaryRepresentation])];
  62. #pragma clang diagnostic pop
  63. }
  64. /**
  65. * Set one or more values in the settings.
  66. * TODO: would it be useful to have a callback for when this has completed?
  67. */
  68. RCT_EXPORT_METHOD(setValues:(NSDictionary *)values)
  69. {
  70. _ignoringUpdates = YES;
  71. [values enumerateKeysAndObjectsUsingBlock:^(NSString *key, id json, BOOL *stop) {
  72. id plist = [RCTConvert NSPropertyList:json];
  73. if (plist) {
  74. [self->_defaults setObject:plist forKey:key];
  75. } else {
  76. [self->_defaults removeObjectForKey:key];
  77. }
  78. }];
  79. [_defaults synchronize];
  80. _ignoringUpdates = NO;
  81. }
  82. /**
  83. * Remove some values from the settings.
  84. */
  85. RCT_EXPORT_METHOD(deleteValues:(NSArray<NSString *> *)keys)
  86. {
  87. _ignoringUpdates = YES;
  88. for (NSString *key in keys) {
  89. [_defaults removeObjectForKey:key];
  90. }
  91. [_defaults synchronize];
  92. _ignoringUpdates = NO;
  93. }
  94. - (std::shared_ptr<facebook::react::TurboModule>)
  95. getTurboModuleWithJsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
  96. nativeInvoker:(std::shared_ptr<facebook::react::CallInvoker>)nativeInvoker
  97. perfLogger:(id<RCTTurboModulePerformanceLogger>)perfLogger
  98. {
  99. return std::make_shared<facebook::react::NativeSettingsManagerSpecJSI>(self, jsInvoker, nativeInvoker, perfLogger);
  100. }
  101. @end
  102. Class RCTSettingsManagerCls(void)
  103. {
  104. return RCTSettingsManager.class;
  105. }