Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: added a persistence layer over keys stored in standard defaults by rudderstack #454

Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
MetricsReporter: 99596ee5003c69949ed2f50acc34aee83c42f843
RSCrashReporter: 6b8376ac729b0289ebe0908553e5f56d8171f313
Rudder: 8091e861028a12add1107b03d224d4abf08c597f
Rudder: c3fd4dca549852fd14153a928979fbced4b901a3
RudderKit: d9d6997696e1642b753d8bdf94e57af643a68f03
SQLCipher: 905b145f65f349f26da9e60a19901ad24adcd381

PODFILE CHECKSUM: b6937cee06e0633464427ff0d975d40e17419e9f

COCOAPODS: 1.14.3
COCOAPODS: 1.14.2
238 changes: 131 additions & 107 deletions Rudder.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "ED04A23B29839DCC0080A88D"
BlueprintIdentifier = "ED99903A2A69103A00031B06"
BuildableName = "RudderTests-iOS.xctest"
BlueprintName = "RudderTests-iOS"
ReferencedContainer = "container:Rudder.xcodeproj">
Expand Down
22 changes: 22 additions & 0 deletions Sources/Classes/Headers/Public/RSDefaultsPersistence.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// RSDefaultsPersistence.h
// Rudder
//
// Created by Desu Sai Venkat on 30/01/24.
//

@interface RSDefaultsPersistence : NSObject {
NSMutableDictionary *data;
NSURL *fileURL;
dispatch_queue_t dataAccessQueue;
}

- (instancetype)init NS_UNAVAILABLE NS_SWIFT_UNAVAILABLE("Use `RSDefaultsPersistence.sharedInstance()` instead.");
+ (instancetype)sharedInstance;
- (void) copyStandardDefaultsToPersistenceIfNeeded;
- (void) clearState;
- (void)writeObject:(id)object forKey:(NSString *)key;
- (id)readObjectForKey:(NSString *)key;
- (void)removeObjectForKey:(NSString *)key;

@end
2 changes: 2 additions & 0 deletions Sources/Classes/Headers/Public/RSEventRepository.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#import "RSElementCache.h"
#import "RSCloudModeManager.h"
#import "RSDeviceModeManager.h"
#import "RSDefaultsPersistence.h"
#import "RSPreferenceManager.h"
#import "RSDBPersistentManager.h"
#import "RSDataResidencyManager.h"
Expand All @@ -37,6 +38,7 @@ NS_ASSUME_NONNULL_BEGIN
RSDataResidencyManager* dataResidencyManager;
RSServerConfigManager* configManager;
RSNetworkManager* networkManager;
RSDefaultsPersistence* defaultsPersistence;
RSPreferenceManager *preferenceManager;
RSCloudModeManager *cloudModeManager;
RSDeviceModeManager *deviceModeManager;
Expand Down
5 changes: 4 additions & 1 deletion Sources/Classes/Headers/Public/RSPreferenceManager.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
//
// RSPreferenceManager.h
// Pods-DummyTestProject
// Rudder
//
// Created by Arnab Pal on 27/01/20.
//

#import <Foundation/Foundation.h>
#import "RSDefaultsPersistence.h"

NS_ASSUME_NONNULL_BEGIN

Expand All @@ -25,6 +26,7 @@ extern NSString *const RSLastActiveTimestamp;
extern NSString *const RSSessionAutoTrackStatus;

+ (instancetype) getInstance;
+ (NSArray *) getPreferenceKeys;

- (void) updateLastUpdatedTime: (long) updatedTime;
- (long) getLastUpdatedTime;
Expand All @@ -41,6 +43,7 @@ extern NSString *const RSSessionAutoTrackStatus;
- (void) deleteBuildVersionCode;

- (void) performMigration;
- (void) restoreMissingKeysFromPersistence;

- (NSString* __nullable) getBuildNumber;
- (void) saveBuildNumber: (NSString* __nonnull) buildNumber;
Expand Down
2 changes: 2 additions & 0 deletions Sources/Classes/Headers/Public/RSUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ NS_ASSUME_NONNULL_BEGIN

+ (NSString*) getTimestamp;
+ (NSString *)getFilePath:(NSString *)fileName;
+ (NSURL *)getFileURL:(NSString *) fileName;
+ (long) getTimeStampLong;
+ (NSString*) getUniqueId;
+ (NSString*) getLocale;
Expand All @@ -43,6 +44,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (BOOL) isApplicationUpdated;
+ (NSString* _Nullable) getDeviceId;
+ (BOOL)isFileExists:(NSString *)fileName;
+ (BOOL)doesFileExistsAtURL:(NSURL *)fileURL;
+ (BOOL)removeFile:(NSString *)fileName;
+ (BOOL) isDBMessageEmpty:(RSDBMessage*)dbMessage;
+ (BOOL) isEmptyString:(NSString *)value;
Expand Down
115 changes: 115 additions & 0 deletions Sources/Classes/RSDefaultsPersistence.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
//
// RSDefaultsPersistence.m
// Rudder
//
// Created by Desu Sai Venkat on 30/01/24.
//

#import <Foundation/Foundation.h>
#import "RSUtils.h"
#import "RSLogger.h"
#import "RSDefaultsPersistence.h"

static RSDefaultsPersistence *instance;
static NSString * const standardDefaultsCopied = @"standardDefaultsCopied";

@implementation RSDefaultsPersistence

+ (instancetype)sharedInstance {
if(instance == nil) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
});
}
return instance;
}

- (instancetype)init {
self = [super init];
if (self) {
data = [NSMutableDictionary dictionary];
fileURL = [RSUtils getFileURL:@"rsDefaultsPersistence.plist"];
dataAccessQueue = dispatch_queue_create("com.rudderstack.defaultspersistence", DISPATCH_QUEUE_SERIAL);
[self loadFromFile];
}
return self;
}

- (void)loadFromFile {
if ([RSUtils doesFileExistsAtURL:fileURL]) {
NSError *error = nil;
NSDictionary* dictFromFile = [NSMutableDictionary dictionaryWithContentsOfURL:fileURL error:&error];
if (error == nil && dictFromFile != nil) {
[data addEntriesFromDictionary:dictFromFile];
}
}
}

// this would be executed only once after the SDK has been updated from a version without DefaultsPersistence
// to a version with DefaultsPersistence to ensure that the persistence layer and standard defaults are in same state.
- (void)copyStandardDefaultsToPersistenceIfNeeded {
BOOL userDefaultsCopiedAlready = [self readObjectForKey:standardDefaultsCopied];
if(!userDefaultsCopiedAlready) {
[RSLogger logDebug:@"RSDefaultsPersistence: copyStandardDefaultsToPersistenceIfNeeded: Copying Standard Defaults to Persistence layer"];
NSArray* preferenceKeys = [RSPreferenceManager getPreferenceKeys];
for(NSString* key in preferenceKeys) {
id value = [[NSUserDefaults standardUserDefaults] objectForKey:key];
if(value != nil) {
[self writeObject:value forKey:key];
}
}
// Set the flag to indicate that standard defaults have been copied to the persistence layer
[self writeObject:@YES forKey:standardDefaultsCopied];
}
}

// the caller of this method should ensure that this is dispatched to the dataAccessQueue synchronously
- (void)writeToFile {
NSError* error = nil;
[data writeToURL:fileURL error:&error];
if (error != nil) {
[RSLogger logError: [NSString stringWithFormat:@"RSDefaultsPersistence: writeToFile: Error writing to file: %@", error]];
}
}

- (void) writeToFileSync {
dispatch_sync(dataAccessQueue, ^{
[self writeToFile];
});
}

- (void)writeObject:(id)object forKey:(NSString *)key {
dispatch_sync(dataAccessQueue, ^{
if (object && key) {
data[key] = object;
[self writeToFile];
}
});
}

- (id)readObjectForKey:(NSString *)key {
__block id result;
dispatch_sync(dataAccessQueue, ^{
result = data[key];
});
return result;

}

- (void)removeObjectForKey:(NSString *)key {
dispatch_sync(dataAccessQueue, ^{
[data removeObjectForKey:key];
[self writeToFile];
});
}

// for testing purpose only
- (void) clearState {
dispatch_sync(dataAccessQueue, ^{
[data removeAllObjects];
[self writeToFile];
});
}

@end
5 changes: 5 additions & 0 deletions Sources/Classes/RSEventRepository.m
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,14 @@ - (instancetype)init:(NSString*)_writeKey config:(RSConfig*)_config client:(RSCl

self->authToken = [RSUtils getBase64EncodedString: [[NSString alloc] initWithFormat:@"%@:", self->writeKey]];

[RSLogger logDebug:@"EventRepository: Initiating DefaultsPersistence"];
self->defaultsPersistence = [RSDefaultsPersistence sharedInstance];
[self->defaultsPersistence copyStandardDefaultsToPersistenceIfNeeded];

[RSLogger logDebug:@"EventRepository: Initiating RSPreferenceManager"];
self->preferenceManager = [RSPreferenceManager getInstance];
[self->preferenceManager performMigration];
[self->preferenceManager restoreMissingKeysFromPersistence];

[self clearAnonymousIdIfRequired];

Expand Down
Loading
Loading