Skip to content

Commit

Permalink
Add anonymous ID retrieval method
Browse files Browse the repository at this point in the history
  • Loading branch information
f2prateek committed Jun 30, 2016
1 parent 0125804 commit b8aed96
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 51 deletions.
4 changes: 2 additions & 2 deletions Example/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
PODS:
- Analytics (3.2.2)
- Analytics (3.2.4)
- Expecta (1.0.3)
- Specta (1.0.4)

Expand All @@ -13,7 +13,7 @@ EXTERNAL SOURCES:
:path: ../

SPEC CHECKSUMS:
Analytics: d7a22ef3048638755e74337f4c31eba35be680d3
Analytics: d801f32615853ca3108216423dbaa829c74f5927
Expecta: 9d1bff6c8b0eeee73a166a2ee898892478927a15
Specta: 69bb134672aae190a1379ff91df07dad8dd1f869

Expand Down
1 change: 1 addition & 0 deletions Pod/Classes/Internal/SEGAnalyticsUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#import <Foundation/Foundation.h>

NSURL *SEGAnalyticsURLForFilename(NSString *filename);
NSString *GenerateUUIDString();

// Date Utils
NSString *iso8601FormattedString(NSDate *date);
Expand Down
8 changes: 8 additions & 0 deletions Pod/Classes/Internal/SEGAnalyticsUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@
return [[NSURL alloc] initFileURLWithPath:[supportPath stringByAppendingPathComponent:filename]];
}

NSString *GenerateUUIDString()
{
CFUUIDRef theUUID = CFUUIDCreate(NULL);
NSString *UUIDString = (__bridge_transfer NSString *)CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
return UUIDString;
}

// Date Utils
NSString *iso8601FormattedString(NSDate *date)
{
Expand Down
1 change: 0 additions & 1 deletion Pod/Classes/Internal/SEGSegmentIntegration.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ extern NSString *const SEGSegmentRequestDidFailNotification;

@interface SEGSegmentIntegration : NSObject <SEGIntegration>

@property (nonatomic, copy) NSString *anonymousId;
@property (nonatomic, copy) NSString *userId;
@property (nonatomic, strong) NSURL *apiURL;

Expand Down
49 changes: 2 additions & 47 deletions Pod/Classes/Internal/SEGSegmentIntegration.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,9 @@
NSString *const SEGADClientClass = @"ADClient";

NSString *const SEGUserIdKey = @"SEGUserId";
NSString *const SEGAnonymousIdKey = @"SEGAnonymousId";
NSString *const SEGQueueKey = @"SEGQueue";
NSString *const SEGTraitsKey = @"SEGTraits";

static NSString *GenerateUUIDString()
{
CFUUIDRef theUUID = CFUUIDCreate(NULL);
NSString *UUIDString = (__bridge_transfer NSString *)CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
return UUIDString;
}

static NSString *GetDeviceModel()
{
size_t size;
Expand Down Expand Up @@ -84,7 +75,6 @@ - (id)initWithAnalytics:(SEGAnalytics *)analytics
if (self = [super init]) {
self.configuration = [analytics configuration];
self.apiURL = [NSURL URLWithString:@"https://api.segment.io/v1/import"];
self.anonymousId = [self getAnonymousId:NO];
self.userId = [self getUserId];
self.bluetooth = [[SEGBluetooth alloc] init];
self.reachability = [SEGReachability reachabilityWithHostname:@"google.com"];
Expand Down Expand Up @@ -284,15 +274,6 @@ - (void)saveUserId:(NSString *)userId
}];
}

- (void)saveAnonymousId:(NSString *)anonymousId
{
[self dispatchBackground:^{
self.anonymousId = anonymousId;
[[NSUserDefaults standardUserDefaults] setValue:anonymousId forKey:SEGAnonymousIdKey];
[self.anonymousId writeToURL:self.anonymousIDURL atomically:YES encoding:NSUTF8StringEncoding error:NULL];
}];
}

- (void)addTraits:(NSDictionary *)traits
{
[self dispatchBackground:^{
Expand All @@ -308,9 +289,6 @@ - (void)identify:(SEGIdentifyPayload *)payload
[self dispatchBackground:^{
[self saveUserId:payload.userId];
[self addTraits:payload.traits];
if (payload.anonymousId) {
[self saveAnonymousId:payload.anonymousId];
}
}];

NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
Expand Down Expand Up @@ -351,7 +329,7 @@ - (void)alias:(SEGAliasPayload *)payload
{
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[dictionary setValue:payload.theNewId forKey:@"userId"];
[dictionary setValue:self.userId ?: self.anonymousId forKey:@"previousId"];
[dictionary setValue:self.userId ?: [self.analytics getAnonymousId] forKey:@"previousId"];

[self enqueueAction:@"alias" dictionary:dictionary context:payload.context integrations:payload.integrations];
}
Expand Down Expand Up @@ -402,7 +380,7 @@ - (void)enqueueAction:(NSString *)action dictionary:(NSMutableDictionary *)paylo
if (![action isEqualToString:@"alias"]) {
[payload setValue:self.userId forKey:@"userId"];
}
[payload setValue:self.anonymousId forKey:@"anonymousId"];
[payload setValue:[self.analytics getAnonymousId] forKey:@"anonymousId"];

[payload setValue:[self integrationsDictionary:integrations] forKey:@"integrations"];

Expand Down Expand Up @@ -506,14 +484,12 @@ - (void)reset
{
[self dispatchBackgroundAndWait:^{
[[NSUserDefaults standardUserDefaults] setValue:nil forKey:SEGUserIdKey];
[[NSUserDefaults standardUserDefaults] setValue:nil forKey:SEGAnonymousIdKey];
[[NSFileManager defaultManager] removeItemAtURL:self.userIDURL error:NULL];
[[NSFileManager defaultManager] removeItemAtURL:self.traitsURL error:NULL];
[[NSFileManager defaultManager] removeItemAtURL:self.queueURL error:NULL];
self.userId = nil;
self.traits = [NSMutableDictionary dictionary];
self.queue = [NSMutableArray array];
self.anonymousId = [self getAnonymousId:YES];
self.request.completion = nil;
self.request = nil;
}];
Expand Down Expand Up @@ -602,11 +578,6 @@ - (NSURL *)userIDURL
return SEGAnalyticsURLForFilename(@"segmentio.userId");
}

- (NSURL *)anonymousIDURL
{
return SEGAnalyticsURLForFilename(@"segment.anonymousId");
}

- (NSURL *)queueURL
{
return SEGAnalyticsURLForFilename(@"segmentio.queue.plist");
Expand All @@ -617,22 +588,6 @@ - (NSURL *)traitsURL
return SEGAnalyticsURLForFilename(@"segmentio.traits.plist");
}

- (NSString *)getAnonymousId:(BOOL)reset
{
// We've chosen to generate a UUID rather than use the UDID (deprecated in iOS 5),
// identifierForVendor (iOS6 and later, can't be changed on logout),
// or MAC address (blocked in iOS 7). For more info see https://segment.io/libraries/ios#ids
NSURL *url = self.anonymousIDURL;
NSString *anonymousId = [[NSUserDefaults standardUserDefaults] valueForKey:SEGAnonymousIdKey] ?: [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:NULL];
if (!anonymousId || reset) {
anonymousId = GenerateUUIDString();
SEGLog(@"New anonymousId: %@", anonymousId);
[[NSUserDefaults standardUserDefaults] setObject:anonymousId forKey:SEGAnonymousIdKey];
[anonymousId writeToURL:url atomically:YES encoding:NSUTF8StringEncoding error:NULL];
}
return anonymousId;
}

- (NSString *)getUserId
{
return [[NSUserDefaults standardUserDefaults] valueForKey:SEGUserIdKey] ?: [[NSString alloc] initWithContentsOfURL:self.userIDURL encoding:NSUTF8StringEncoding error:NULL];
Expand Down
3 changes: 3 additions & 0 deletions Pod/Classes/SEGAnalytics.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,9 @@ extern NSString *SEGAnalyticsIntegrationDidStart;
*/
- (NSDictionary *)bundledIntegrations;

/** Returns the anonymous ID. */
- (NSString *)getAnonymousId;

/** Returns the configuration used to create the analytics client. */
- (SEGAnalyticsConfiguration *)configuration;

Expand Down
53 changes: 52 additions & 1 deletion Pod/Classes/SEGAnalytics.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

static SEGAnalytics *__sharedInstance = nil;
NSString *SEGAnalyticsIntegrationDidStart = @"io.segment.analytics.integration.did.start";
NSString *const SEGAnonymousIdKey = @"SEGAnonymousId";


@interface SEGAnalyticsConfiguration ()
Expand Down Expand Up @@ -77,6 +78,7 @@ @interface SEGAnalytics ()
@property (nonatomic, strong) NSMutableDictionary *registeredIntegrations;
@property (nonatomic) volatile BOOL initialized;
@property (nonatomic, strong) SEGStoreKitTracker *storeKitTracker;
@property (nonatomic, copy) NSString *cachedAnonymousId;

@end

Expand Down Expand Up @@ -106,6 +108,7 @@ - (instancetype)initWithConfiguration:(SEGAnalyticsConfiguration *)configuration
self.integrations = [NSMutableDictionary dictionaryWithCapacity:self.factories.count];
self.registeredIntegrations = [NSMutableDictionary dictionaryWithCapacity:self.factories.count];
self.configuration = configuration;
self.cachedAnonymousId = [self loadOrGenerateAnonymousID:NO];

// Update settings on each integration immediately
[self refreshSettings];
Expand Down Expand Up @@ -242,12 +245,20 @@ - (void)identify:(NSString *)userId traits:(NSDictionary *)traits options:(NSDic
{
NSCAssert2(userId.length > 0 > traits.count > 0, @"either userId (%@) or traits (%@) must be provided.", userId, traits);

NSString *anonymousId = [options objectForKey:@"anonymousId"];
if (anonymousId) {
[self saveAnonymousId:anonymousId];
} else {
anonymousId = self.cachedAnonymousId;
}

SEGIdentifyPayload *payload = [[SEGIdentifyPayload alloc] initWithUserId:userId
anonymousId:[options objectForKey:@"anonymousId"]
anonymousId:anonymousId
traits:SEGCoerceDictionary(traits)
context:SEGCoerceDictionary([options objectForKey:@"context"])
integrations:[options objectForKey:@"integrations"]];


[self callIntegrationsWithSelector:NSSelectorFromString(@"identify:")
arguments:@[ payload ]
options:options
Expand Down Expand Up @@ -376,9 +387,49 @@ - (void)handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:

- (void)reset
{
[self resetAnonymousId];
[self callIntegrationsWithSelector:_cmd arguments:nil options:nil sync:false];
}

- (void)resetAnonymousId
{
[[NSUserDefaults standardUserDefaults] setValue:nil forKey:SEGAnonymousIdKey];
self.cachedAnonymousId = [self loadOrGenerateAnonymousID:YES];
}

- (NSString *)getAnonymousId;
{
return self.cachedAnonymousId;
}

- (NSURL *)anonymousIDURL
{
return SEGAnalyticsURLForFilename(@"segment.anonymousId");
}

- (NSString *)loadOrGenerateAnonymousID:(BOOL)reset
{
// We've chosen to generate a UUID rather than use the UDID (deprecated in iOS 5),
// identifierForVendor (iOS6 and later, can't be changed on logout),
// or MAC address (blocked in iOS 7). For more info see https://segment.io/libraries/ios#ids
NSURL *url = self.anonymousIDURL;
NSString *anonymousId = [[NSUserDefaults standardUserDefaults] valueForKey:SEGAnonymousIdKey] ?: [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:NULL];
if (!anonymousId || reset) {
anonymousId = GenerateUUIDString();
SEGLog(@"New anonymousId: %@", anonymousId);
[[NSUserDefaults standardUserDefaults] setObject:anonymousId forKey:SEGAnonymousIdKey];
[anonymousId writeToURL:url atomically:YES encoding:NSUTF8StringEncoding error:NULL];
}
return anonymousId;
}

- (void)saveAnonymousId:(NSString *)anonymousId
{
self.cachedAnonymousId = anonymousId;
[[NSUserDefaults standardUserDefaults] setValue:anonymousId forKey:SEGAnonymousIdKey];
[self.cachedAnonymousId writeToURL:self.anonymousIDURL atomically:YES encoding:NSUTF8StringEncoding error:NULL];
}

- (void)flush
{
[self callIntegrationsWithSelector:_cmd arguments:nil options:nil sync:false];
Expand Down

0 comments on commit b8aed96

Please sign in to comment.