react-native/Libraries/Settings/RCTSettingsManager.m
Ramanpreet Nara f37093319b Start using getConstants
Summary:
TurboModules depend on a getConstants method. Existing ObjectiveC modules do not have this method. Therefore, I moved the contents of `constantsToExport` to `getConstants` and then had `constantsToExports` call `getConstants`.

facebook
Since all NativeModules will eventually need to be migrated to the TurboModule system, I didn't restrict this to just the NativeModules in Marketplace.

```
const fs = require('fs');

if (process.argv.length < 3) {
    throw new Error('Expected a file containing a list of native modules as the third param');
}

function read(filename) {
    return fs.readFileSync(filename, 'utf8');
}

const nativeModuleFilenames = read(process.argv[2]).split('\n').filter(Boolean);

nativeModuleFilenames.forEach((fileName) => {
    if (fileName.endsWith('.h')) {
        return;
    }

    const absPath = `${process.env.HOME}/${fileName}`;
    const fileSource = read(absPath);

    if (/(\n|^)-\s*\((.+)\)getConstants/.test(fileSource)) {
        return;
    }

    const constantsToExportRegex = /(\n|^)-\s*\((.+)\)constantsToExport/;
    const result = constantsToExportRegex.exec(fileSource);

    if (result == null) {
        throw new Error(`Didn't find a constantsToExport function inside NativeModule ${fileName}`);
    }

    const returnType = result[2];

    const newFileSource = fileSource.replace(
        constantsToExportRegex,
        '$1- ($2)constantsToExport\n' +
        '{\n' +
        `  return ${returnType.includes('ModuleConstants') ? '($2)' : ''}[self getConstants];\n` +
        '}\n' +
        '\n' +
        '- ($2)getConstants'
    );

    fs.writeFileSync(absPath, newFileSource);
});
```

```
> xbgs -l ')constantsToExport'
```

Reviewed By: fkgozali

Differential Revision: D13951197

fbshipit-source-id: 394a319d42aff466c56a3d748e17c335307a8f47
2019-02-04 17:46:56 -08:00

113 lines
2.5 KiB
Objective-C

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTSettingsManager.h"
#import <React/RCTBridge.h>
#import <React/RCTConvert.h>
#import <React/RCTEventDispatcher.h>
#import <React/RCTUtils.h>
@implementation RCTSettingsManager
{
BOOL _ignoringUpdates;
NSUserDefaults *_defaults;
}
@synthesize bridge = _bridge;
RCT_EXPORT_MODULE()
+ (BOOL)requiresMainQueueSetup
{
return NO;
}
- (instancetype)init
{
return [self initWithUserDefaults:[NSUserDefaults standardUserDefaults]];
}
- (instancetype)initWithUserDefaults:(NSUserDefaults *)defaults
{
if ((self = [super init])) {
_defaults = defaults;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(userDefaultsDidChange:)
name:NSUserDefaultsDidChangeNotification
object:_defaults];
}
return self;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (NSDictionary<NSString *, id> *)constantsToExport
{
return [self getConstants];
}
- (NSDictionary<NSString *, id> *)getConstants
{
return @{@"settings": RCTJSONClean([_defaults dictionaryRepresentation])};
}
- (void)userDefaultsDidChange:(NSNotification *)note
{
if (_ignoringUpdates) {
return;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[_bridge.eventDispatcher
sendDeviceEventWithName:@"settingsUpdated"
body:RCTJSONClean([_defaults dictionaryRepresentation])];
#pragma clang diagnostic pop
}
/**
* Set one or more values in the settings.
* TODO: would it be useful to have a callback for when this has completed?
*/
RCT_EXPORT_METHOD(setValues:(NSDictionary *)values)
{
_ignoringUpdates = YES;
[values enumerateKeysAndObjectsUsingBlock:^(NSString *key, id json, BOOL *stop) {
id plist = [RCTConvert NSPropertyList:json];
if (plist) {
[self->_defaults setObject:plist forKey:key];
} else {
[self->_defaults removeObjectForKey:key];
}
}];
[_defaults synchronize];
_ignoringUpdates = NO;
}
/**
* Remove some values from the settings.
*/
RCT_EXPORT_METHOD(deleteValues:(NSArray<NSString *> *)keys)
{
_ignoringUpdates = YES;
for (NSString *key in keys) {
[_defaults removeObjectForKey:key];
}
[_defaults synchronize];
_ignoringUpdates = NO;
}
@end