Skip to content

Commit

Permalink
Extrernal Id implementation in identify call
Browse files Browse the repository at this point in the history
  • Loading branch information
arnab-p committed Sep 21, 2020
1 parent 5ff1951 commit cd4be95
Show file tree
Hide file tree
Showing 16 changed files with 154 additions and 17 deletions.
6 changes: 3 additions & 3 deletions Example/Rudder/_AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#import <Rudder/Rudder.h>
#import <AdSupport/ASIdentifierManager.h>

static NSString *DATA_PLANE_URL = @"https://hosted.rudderlabs.com";
static NSString *DATA_PLANE_URL = @"https://7f79d5a74811.ngrok.io";
static NSString *WRITE_KEY = @"1celWezYSkGPQzL0foc9dnvFfsD";

@implementation _AppDelegate
Expand All @@ -21,8 +21,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
RSConfigBuilder *builder = [[RSConfigBuilder alloc] init];
[builder withDataPlaneURL:[[NSURL alloc] initWithString:DATA_PLANE_URL]];
[builder withLoglevel:RSLogLevelDebug];
[builder withTrackLifecycleEvens:YES];
[builder withRecordScreenViews:YES];
[builder withTrackLifecycleEvens:NO];
[builder withRecordScreenViews:NO];
[RSClient getInstance:WRITE_KEY config:[builder build]];

// [[[RSClient sharedInstance] getContext] putDeviceToken:[self getDeviceToken]];
Expand Down
14 changes: 11 additions & 3 deletions Example/Rudder/_ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,18 @@ - (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

[[RSClient sharedInstance] track:@"Test Event 1"];
[[RSClient sharedInstance] reset];
[[RSClient sharedInstance] track:@"Test Event 2"];
[[RSClient sharedInstance] track:@"Test Event 3"];
[[RSClient sharedInstance] track:@"Test Event 4"];
// [[RSClient sharedInstance] track:@"Test Event 2"];
// [[RSClient sharedInstance] track:@"Test Event 3"];
// [[RSClient sharedInstance] track:@"Test Event 4"];

// RSOption *identifyOptions = [[RSOption alloc] init];
// [identifyOptions putExternalId:@"brazeExternalId" withId:@"some_external_id_1"];
// [identifyOptions putExternalId:@"braze_id" withId:@"some_braze_id_2"];
// [[RSClient sharedInstance] identify:@"testUserId"
// traits:@{@"firstname": @"First Name"}
// options:identifyOptions];
}

- (void)didReceiveMemoryWarning
Expand Down
15 changes: 11 additions & 4 deletions Rudder/Classes/RSClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,16 @@ - (void) dumpInternal:(RSMessage *)message type:(NSString*) type {
if (type == RSIdentify) {
[RSElementCache updateTraitsDict:message.context.traits];
[RSElementCache persistTraits];

// handle external Ids
RSOption *option = message.option;
if (option != nil) {
NSMutableArray *externalIds = option.externalIds;
if (externalIds != nil) {
[RSElementCache updateExternalIds:externalIds];
}
}
}

message.type = type;
[_repository dump:message];
}
Expand Down Expand Up @@ -195,15 +203,14 @@ - (void)identify:(NSString *)userId traits:(NSDictionary *)traits {
[self dumpInternal:[builder build] type:RSIdentify];
}

- (void)identify:(NSString *)userId traits:(NSDictionary *)traits options:(NSDictionary *)options {
- (void)identify:(NSString *)userId traits:(NSDictionary *)traits options:(RSOption *)options {
RSTraits *traitsObj = [[RSTraits alloc] initWithDict:traits];
[traitsObj setUserId:userId];
RSMessageBuilder *builder = [[RSMessageBuilder alloc] init];
[builder setEventName:RSIdentify];
[builder setUserId:userId];
[builder setTraits:traitsObj];
RSOption *optionsObj = [[RSOption alloc] initWithDict:options];
[builder setRSOption:optionsObj];
[builder setRSOption:options];
[self dumpInternal:[builder build] type:RSIdentify];
}

Expand Down
2 changes: 2 additions & 0 deletions Rudder/Classes/RSContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readwrite) RSDeviceInfo* device;
@property (nonatomic, readwrite) RSNetwork* network;
@property (nonatomic, readwrite) NSString* timezone;
@property (nonatomic, readwrite) NSMutableArray* externalIds;

- (NSDictionary<NSString* , NSObject *>*) dict;
- (void) updateTraits: (RSTraits* _Nullable) traits;
- (void) persistTraits;
- (void) updateTraitsDict: (NSMutableDictionary<NSString*, NSObject*>*) traitsDict;
- (void) putDeviceToken: (NSString*) deviceToken;
- (void) putAdvertisementId: (NSString*) idfa;
- (void) updateExternalIds: (NSMutableArray* __nullable) externalIds;

@end

Expand Down
32 changes: 30 additions & 2 deletions Rudder/Classes/RSContext.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ - (instancetype)init
_locale = [RSUtils getLocale];
_network = [[RSNetwork alloc] init];
_timezone = [[NSTimeZone localTimeZone] name];
_externalIds = nil;

NSString *traitsJson = [preferenceManager getTraits];
if (traitsJson == nil) {
Expand All @@ -52,6 +53,16 @@ - (instancetype)init
[self createAndPersistTraits];
}
}

// get saved external Ids from prefs
NSString *externalIdJson = [preferenceManager getExternalIds];
if (externalIdJson != nil) {
NSError *error;
NSDictionary *externalIdDict = [NSJSONSerialization JSONObjectWithData:[externalIdJson dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&error];
if (error == nil) {
_externalIds = [externalIdDict mutableCopy];
}
}
}
return self;
}
Expand All @@ -70,8 +81,6 @@ - (void)updateTraits:(RSTraits *)traits {
traits.anonymousId = _device.identifier;
}

// _traits = [[traits dict] mutableCopy];

[_traits setValuesForKeysWithDictionary:[traits dict]];
}

Expand Down Expand Up @@ -109,6 +118,22 @@ - (void)putAdvertisementId:(NSString *)idfa {
}
}

- (void)updateExternalIds:(NSMutableArray *)externalIds {
// update local variable
_externalIds = externalIds;

if (externalIds != nil) {
// update persistence storage
NSData *externalIdJsonData = [NSJSONSerialization dataWithJSONObject:[RSUtils serializeArray:[externalIds copy]] options:0 error:nil];
NSString *externalIdJson = [[NSString alloc] initWithData:externalIdJsonData encoding:NSUTF8StringEncoding];

[preferenceManager saveExternalIds:externalIdJson];
} else {
// clear persistence storage : RESET call
[preferenceManager clearExternalIds];
}
}

- (NSDictionary<NSString *,NSObject *> *)dict {
NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] init];
[tempDict setObject:[_app dict] forKey:@"app"];
Expand All @@ -121,6 +146,9 @@ - (void)putAdvertisementId:(NSString *)idfa {
[tempDict setObject:[_device dict] forKey:@"device"];
[tempDict setObject:[_network dict] forKey:@"network"];
[tempDict setObject:_timezone forKey:@"timezone"];
if (_externalIds != nil) {
[tempDict setObject:_externalIds forKey:@"externalId"];
}

return [tempDict copy];
}
Expand Down
2 changes: 2 additions & 0 deletions Rudder/Classes/RSElementCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ NS_ASSUME_NONNULL_BEGIN

+ (void) updateTraitsDict: (NSMutableDictionary<NSString*, NSObject*> *) traitsDict;

+ (void) updateExternalIds: (NSMutableArray*) externalId;

@end

NS_ASSUME_NONNULL_END
5 changes: 5 additions & 0 deletions Rudder/Classes/RSElementCache.m
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ + (void)persistTraits {
+ (void) reset {
[cachedContext updateTraits:nil];
[cachedContext persistTraits];
[cachedContext updateExternalIds:nil];
}

+ (void)updateTraitsDict:(NSMutableDictionary<NSString *,NSObject *> *)traitsDict {
Expand All @@ -42,4 +43,8 @@ + (void)updateTraitsDict:(NSMutableDictionary<NSString *,NSObject *> *)traitsDic
+ (NSString *)getAnonymousId {
return cachedContext.device.identifier;
}

+ (void) updateExternalIds:(NSMutableArray *)externalId {
[cachedContext updateExternalIds:externalId];
}
@end
3 changes: 3 additions & 0 deletions Rudder/Classes/RSMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#import <Foundation/Foundation.h>
#import "RSContext.h"
#import "RSOption.h"

NS_ASSUME_NONNULL_BEGIN

Expand All @@ -29,11 +30,13 @@ NS_ASSUME_NONNULL_BEGIN
@property (atomic, readwrite) NSDictionary<NSString *, NSObject *>* userProperties;
@property (atomic, readwrite) NSDictionary<NSString *, NSObject *>* integrations;
@property (atomic, readwrite) NSString* destinationProps;
@property (atomic, readwrite) RSOption* option;

- (NSDictionary<NSString*, NSObject*>*) dict;
- (void) updateContext: (RSContext*) context;
- (void) updateTraits: (RSTraits*) traits;
- (void) updateTraitsDict:(NSMutableDictionary<NSString *,NSObject *>*)traits;
- (void) setRudderOption: (RSOption*) option;

@end

Expand Down
4 changes: 4 additions & 0 deletions Rudder/Classes/RSMessage.m
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,8 @@ - (void)updateTraits:(RSTraits *)traits {
- (void)updateTraitsDict:(NSMutableDictionary<NSString *,NSObject *>*)traits {
[_context updateTraitsDict:traits];
}

- (void)setRudderOption:(RSOption *)option {
_option = option;
}
@end
2 changes: 2 additions & 0 deletions Rudder/Classes/RSMessageBuilder.m
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ - (instancetype) setRSOption:(RSOption *)option {
message = [[RSMessage alloc] init];
}

[message setRudderOption:option];

return self;
}

Expand Down
4 changes: 3 additions & 1 deletion Rudder/Classes/RSOption.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ NS_ASSUME_NONNULL_BEGIN

@interface RSOption : NSObject

- (instancetype) initWithDict:(NSDictionary*) options;
@property (nonatomic, strong) NSMutableArray<NSMutableDictionary<NSString*, NSObject*>*>* externalIds;

- (instancetype) putExternalId: (NSString*) type withId: (NSString*) idValue;

@end

Expand Down
44 changes: 42 additions & 2 deletions Rudder/Classes/RSOption.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,52 @@

@implementation RSOption

- (instancetype)initWithDict:(NSDictionary *)options {
- (instancetype)init
{
self = [super init];
if (self) {

_externalIds = nil;
}
return self;
}

- (instancetype)putExternalId:(NSString *)type withId:(NSString *)idValue {
if (_externalIds == nil) {
_externalIds = [[NSMutableArray alloc] init];
}

// find out if something is already present in the storage (PreferenceManager)
NSMutableDictionary* externalIdDict = nil;
int dictIndex = -1;
for (int index = 0; index < _externalIds.count; index += 1) {
NSMutableDictionary* dict = _externalIds[index];
NSString* dictType = dict[@"type"];
if (dictType != nil && [dictType isEqual:type]) {
externalIdDict = dict;
dictIndex = index;
break;
}
}

// if not present from previous runs: create new and assign the type
if (externalIdDict == nil) {
externalIdDict = [[NSMutableDictionary alloc] initWithDictionary:@{
@"type": type
}];
}

// assign new id or update existing id
[externalIdDict setValue:idValue forKey:@"id"];

// finally update existing position or add new id
if (dictIndex == -1) {
[_externalIds addObject:externalIdDict];
} else {
_externalIds[dictIndex][@"id"] = idValue;
}

// return for builder pattern
return self;
}

@end
5 changes: 5 additions & 0 deletions Rudder/Classes/RSPreferenceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ extern NSString *const RSServerConfigKey;
extern NSString *const RSServerLastUpdatedKey;
extern NSString *const RSTraitsKey;
extern NSString *const RSApplicationInfoKey;
extern NSString *const RSExternalIdKey;

+ (instancetype) getInstance;

Expand All @@ -31,6 +32,10 @@ extern NSString *const RSApplicationInfoKey;
- (NSString* __nullable) getBuildVersionCode;
- (void) saveBuildVersionCode: (NSString* __nonnull) versionCode;

- (NSString* __nullable) getExternalIds;
- (void) saveExternalIds: (NSString* __nonnull) externalIdsJson;
- (void) clearExternalIds;

@end

NS_ASSUME_NONNULL_END
15 changes: 15 additions & 0 deletions Rudder/Classes/RSPreferenceManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ @implementation RSPreferenceManager
NSString *const RSServerLastUpdatedKey = @"rl_server_last_updated";
NSString *const RSTraitsKey = @"rl_traits";
NSString *const RSApplicationInfoKey = @"rl_application_info_key";
NSString *const RSExternalIdKey = @"rl_external_id";

+ (instancetype)getInstance {
if (instance == nil) {
Expand Down Expand Up @@ -65,4 +66,18 @@ - (NSString *)getBuildVersionCode {
return [[NSUserDefaults standardUserDefaults] valueForKey:RSApplicationInfoKey];
}

- (NSString *)getExternalIds {
return [[NSUserDefaults standardUserDefaults] valueForKey:RSExternalIdKey];
}

- (void)saveExternalIds:(NSString *)externalIdsJson {
[[NSUserDefaults standardUserDefaults] setValue:externalIdsJson forKey:RSExternalIdKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}

- (void)clearExternalIds {
[[NSUserDefaults standardUserDefaults] setValue:nil forKey:RSExternalIdKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}

@end
1 change: 1 addition & 0 deletions Rudder/Classes/RSUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (NSString*) getDateString: (NSDate*) date;
+ (unsigned int) getUTF8Length: (NSString*) message;
+ (NSDictionary<NSString*, id>*) serializeDict: (NSDictionary<NSString*, id>* _Nullable) dict;
+ (NSArray*) serializeArray: (NSArray*) array;

extern unsigned int MAX_EVENT_SIZE;
extern unsigned int MAX_BATCH_SIZE;
Expand Down
17 changes: 15 additions & 2 deletions Rudder/Classes/RSUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,14 @@ + (id) serializeValue: (id) val {
[array addObject:[self serializeValue:i]];
}
return [array copy];
} else if ([val isKindOfClass:[NSDictionary class]]) {
} else if ([val isKindOfClass:[NSDictionary class]] ||
[val isKindOfClass:[NSMutableDictionary class]]
) {
// handle dictionary
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
NSArray *keys = [val allKeys];
for (NSString *key in keys) {
id value = [dict objectForKey:key];
id value = [val objectForKey:key];
if (![key isKindOfClass:[NSString class]]) {
[RSLogger logDebug:@"key should be string. changing it to its description"];
}
Expand Down Expand Up @@ -103,6 +105,17 @@ + (id) serializeValue: (id) val {
return dict;
}

+ (NSArray*) serializeArray:(NSArray*) array {
if (array) {
NSMutableArray *returnArray = [[NSMutableArray alloc] init];
for (id i in array) {
[returnArray addObject:[self serializeValue:i]];
}
return [returnArray copy];
}
return array;
}

unsigned int MAX_EVENT_SIZE = 32 * 1024; // 32 KB
unsigned int MAX_BATCH_SIZE = 500 * 1024; // 500 KB

Expand Down

0 comments on commit cd4be95

Please sign in to comment.