work
This commit is contained in:
parent
568209258f
commit
d7d79748e2
@ -9,11 +9,13 @@ import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import java.util.Map;
|
||||
|
||||
public class RNDefaultPreferenceModule extends ReactContextBaseJavaModule {
|
||||
private String preferencesName;
|
||||
private final SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener;
|
||||
private final ReactApplicationContext reactContext;
|
||||
private boolean hasListeners = false; // Flag to track if listeners are active
|
||||
|
||||
public RNDefaultPreferenceModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
@ -21,11 +23,11 @@ public class RNDefaultPreferenceModule extends ReactContextBaseJavaModule {
|
||||
this.preferencesName = reactContext.getPackageName() + "_preferences";
|
||||
|
||||
preferenceChangeListener = (sharedPreferences, key) -> {
|
||||
if (reactContext.hasActiveCatalystInstance()) {
|
||||
if (hasListeners && reactContext.hasActiveCatalystInstance()) { // Only send events if listeners are active
|
||||
WritableMap changeInfo = Arguments.createMap();
|
||||
changeInfo.putString("key", key);
|
||||
Object value = sharedPreferences.getAll().get(key);
|
||||
|
||||
|
||||
if (value instanceof String) {
|
||||
changeInfo.putString("value", (String) value);
|
||||
} else if (value instanceof Integer) {
|
||||
@ -45,6 +47,7 @@ public class RNDefaultPreferenceModule extends ReactContextBaseJavaModule {
|
||||
.emit("onPreferenceChange", changeInfo);
|
||||
}
|
||||
};
|
||||
|
||||
getPreferences().registerOnSharedPreferenceChangeListener(preferenceChangeListener);
|
||||
}
|
||||
|
||||
@ -53,49 +56,61 @@ public class RNDefaultPreferenceModule extends ReactContextBaseJavaModule {
|
||||
return "RNDefaultPreference";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
hasListeners = true; // Mark that listeners are active when the module is initialized
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCatalystInstanceDestroy() {
|
||||
super.onCatalystInstanceDestroy();
|
||||
hasListeners = false; // Mark that no listeners are active when the module is destroyed
|
||||
getPreferences().unregisterOnSharedPreferenceChangeListener(preferenceChangeListener);
|
||||
}
|
||||
|
||||
private SharedPreferences getPreferences() {
|
||||
return getReactApplicationContext().getSharedPreferences(preferencesName, Context.MODE_PRIVATE);
|
||||
}}
|
||||
|
||||
private SharedPreferences.Editor getEditor() {
|
||||
return getPreferences().edit();
|
||||
}
|
||||
|
||||
private void resolvePreferenceValue(Object value, Promise promise) {
|
||||
if (value instanceof String) {
|
||||
promise.resolve((String) value);
|
||||
} else if (value instanceof Integer) {
|
||||
promise.resolve((Integer) value);
|
||||
} else if (value instanceof Boolean) {
|
||||
promise.resolve((Boolean) value);
|
||||
} else if (value instanceof Float) {
|
||||
promise.resolve((Float) value);
|
||||
} else if (value instanceof Long) {
|
||||
promise.resolve((Long) value);
|
||||
} else {
|
||||
promise.resolve(null);
|
||||
@ReactMethod
|
||||
public void setName(String name, Promise promise) {
|
||||
this.preferencesName = name;
|
||||
promise.resolve(null);
|
||||
}
|
||||
}
|
||||
|
||||
private WritableMap resolvePreferenceToMap(String key, Object value) {
|
||||
WritableMap map = Arguments.createMap();
|
||||
if (value instanceof String) {
|
||||
map.putString(key, (String) value);
|
||||
} else if (value instanceof Integer) {
|
||||
map.putInt(key, (Integer) value);
|
||||
} else if (value instanceof Boolean) {
|
||||
map.putBoolean(key, (Boolean) value);
|
||||
} else if (value instanceof Float) {
|
||||
map.putDouble(key, (Float) value);
|
||||
} else if (value instanceof Long) {
|
||||
map.putDouble(key, ((Long) value).doubleValue());
|
||||
@ReactMethod
|
||||
public void getName(Promise promise) {
|
||||
promise.resolve(preferencesName);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void get(String key, Promise promise) {
|
||||
Object value = getPreferences().getAll().get(key);
|
||||
if (value instanceof String) {
|
||||
promise.resolve((String) value);
|
||||
} else if (value instanceof Integer) {
|
||||
promise.resolve((Integer) value);
|
||||
} else if (value instanceof Boolean) {
|
||||
promise.resolve((Boolean) value);
|
||||
} else if (value instanceof Float) {
|
||||
promise.resolve((Float) value);
|
||||
} else if (value instanceof Long) {
|
||||
promise.resolve((Long) value);
|
||||
} else {
|
||||
promise.resolve(null);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void set(String key, String value, Promise promise) {
|
||||
getPreferences().edit().putString(key, value).apply();
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void clear(String key, Promise promise) {
|
||||
getPreferences().edit().remove(key).apply();
|
||||
promise.resolve(null);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,13 @@
|
||||
#import "RNDefaultPreference.h"
|
||||
#import <React/RCTEventEmitter.h>
|
||||
#import <React/RCTBridgeModule.h>
|
||||
|
||||
@implementation RNDefaultPreference
|
||||
@interface RNDefaultPreference : RCTEventEmitter <RCTBridgeModule>
|
||||
@end
|
||||
|
||||
@implementation RNDefaultPreference {
|
||||
BOOL hasListeners;
|
||||
}
|
||||
|
||||
NSString* defaultSuiteName = nil;
|
||||
|
||||
@ -10,8 +16,8 @@ NSString* defaultSuiteName = nil;
|
||||
return dispatch_get_main_queue();
|
||||
}
|
||||
|
||||
- (NSUserDefaults *) getDefaultUser{
|
||||
if(defaultSuiteName == nil){
|
||||
- (NSUserDefaults *)getDefaultUser {
|
||||
if (defaultSuiteName == nil) {
|
||||
return [NSUserDefaults standardUserDefaults];
|
||||
} else {
|
||||
return [[NSUserDefaults alloc] initWithSuiteName:defaultSuiteName];
|
||||
@ -25,11 +31,22 @@ RCT_EXPORT_MODULE()
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Implement required method for RCTEventEmitter
|
||||
- (NSArray<NSString *> *)supportedEvents
|
||||
{
|
||||
return @[@"onPreferenceChange"];
|
||||
}
|
||||
|
||||
// Called when the first listener is added
|
||||
- (void)startObserving {
|
||||
hasListeners = YES;
|
||||
}
|
||||
|
||||
// Called when the last listener is removed or when the module is deallocated
|
||||
- (void)stopObserving {
|
||||
hasListeners = NO;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
@ -43,13 +60,16 @@ RCT_EXPORT_MODULE()
|
||||
|
||||
- (void)userDefaultsDidChange:(NSNotification *)notification
|
||||
{
|
||||
NSUserDefaults *defaults = [self getDefaultUser];
|
||||
NSDictionary *changedKeys = defaults.dictionaryRepresentation;
|
||||
|
||||
[changedKeys enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
|
||||
NSDictionary *changeInfo = @{@"key": key, @"value": obj};
|
||||
[self sendEventWithName:@"onPreferenceChange" body:changeInfo];
|
||||
}];
|
||||
if (hasListeners) { // Only send events if there are listeners
|
||||
NSUserDefaults *defaults = [self getDefaultUser];
|
||||
NSDictionary *changedKeys = defaults.dictionaryRepresentation;
|
||||
|
||||
for (NSString *key in changedKeys) {
|
||||
id value = [defaults objectForKey:key];
|
||||
NSDictionary *changeInfo = @{@"key": key, @"value": value ?: [NSNull null]};
|
||||
[self sendEventWithName:@"onPreferenceChange" body:changeInfo];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
@ -57,146 +77,44 @@ RCT_EXPORT_MODULE()
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(set:(NSString *)key value:(id)value
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
if ([value isKindOfClass:[NSString class]]) {
|
||||
[[self getDefaultUser] setObject:value forKey:key];
|
||||
} else if ([value isKindOfClass:[NSNumber class]]) {
|
||||
[[self getDefaultUser] setObject:value forKey:key];
|
||||
}
|
||||
[[self getDefaultUser] synchronize];
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
|
||||
RCT_EXPORT_METHOD(setName:(NSString *)name
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(__unused RCTPromiseRejectBlock)reject)
|
||||
reject:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
defaultSuiteName = name;
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getName:(RCTPromiseResolveBlock)resolve
|
||||
reject:(__unused RCTPromiseRejectBlock)reject)
|
||||
reject:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
resolve(defaultSuiteName);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(get:(NSString *)key
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(__unused RCTPromiseRejectBlock)reject)
|
||||
reject:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
id value = [[self getDefaultUser] objectForKey:key];
|
||||
if ([value isKindOfClass:[NSString class]]) {
|
||||
resolve(value);
|
||||
} else if ([value isKindOfClass:[NSNumber class]]) {
|
||||
resolve([NSString stringWithFormat:@"%@", value]);
|
||||
} else if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]]) {
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:value options:0 error:&error];
|
||||
if (!jsonData) {
|
||||
reject(@"error_serializing", @"Could not serialize JSON data", error);
|
||||
} else {
|
||||
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||
resolve(jsonString);
|
||||
}
|
||||
} else {
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
resolve(value ?: [NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(set:(NSString *)key value:(id)value
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(__unused RCTPromiseRejectBlock)reject)
|
||||
reject:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
if ([value isKindOfClass:[NSString class]]) {
|
||||
[[self getDefaultUser] setObject:value forKey:key];
|
||||
} else if ([value isKindOfClass:[NSNumber class]]) {
|
||||
[[self getDefaultUser] setObject:value forKey:key];
|
||||
} else if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]]) {
|
||||
[[self getDefaultUser] setObject:value forKey:key];
|
||||
}
|
||||
NSUserDefaults *defaults = [self getDefaultUser];
|
||||
[defaults setObject:value forKey:key];
|
||||
[defaults synchronize];
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(clear:(NSString *)key
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(__unused RCTPromiseRejectBlock)reject)
|
||||
reject:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
[[self getDefaultUser] removeObjectForKey:key];
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getMultiple:(NSArray *)keys
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(__unused RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
NSMutableArray *result = [NSMutableArray array];
|
||||
for (NSString *key in keys) {
|
||||
id value = [[self getDefaultUser] objectForKey:key];
|
||||
if ([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]]) {
|
||||
[result addObject:value];
|
||||
} else if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]]) {
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:value options:0 error:&error];
|
||||
NSString *jsonString = jsonData ? [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding] : [NSNull null];
|
||||
[result addObject:jsonString];
|
||||
} else {
|
||||
[result addObject:[NSNull null]];
|
||||
}
|
||||
}
|
||||
resolve(result);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setMultiple:(NSDictionary *)data
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(__unused RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
for (id key in data) {
|
||||
id value = data[key];
|
||||
[[self getDefaultUser] setObject:value forKey:key];
|
||||
}
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(clearMultiple:(NSArray *)keys
|
||||
resolve:(RCTPromiseResolveBlock)resolve
|
||||
reject:(__unused RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
for (NSString *key in keys) {
|
||||
[[self getDefaultUser] removeObjectForKey:key];
|
||||
}
|
||||
resolve([NSNull null]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getAll:(RCTPromiseResolveBlock)resolve
|
||||
reject:(__unused RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
NSArray *keys = [[[self getDefaultUser] dictionaryRepresentation] allKeys];
|
||||
NSMutableDictionary *result = [NSMutableDictionary dictionary];
|
||||
for (NSString *key in keys) {
|
||||
id value = [[self getDefaultUser] objectForKey:key];
|
||||
if ([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]]) {
|
||||
result[key] = value;
|
||||
} else if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]]) {
|
||||
NSError *error;
|
||||
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:value options:0 error:&error];
|
||||
result[key] = jsonData ? [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding] : [NSNull null];
|
||||
} else {
|
||||
result[key] = [NSNull null];
|
||||
}
|
||||
}
|
||||
resolve(result);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(clearAll:(RCTPromiseResolveBlock)resolve
|
||||
reject:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
NSArray *keys = [[[self getDefaultUser] dictionaryRepresentation] allKeys];
|
||||
[self clearMultiple:keys resolve:resolve reject:reject];
|
||||
}
|
||||
|
||||
@end
|
||||
Loading…
Reference in New Issue
Block a user