Skip to content

Commit

Permalink
unified identify:
Browse files Browse the repository at this point in the history
  • Loading branch information
neilrahilly committed Apr 24, 2013
1 parent babbb24 commit 6194f18
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 59 deletions.
2 changes: 1 addition & 1 deletion HelloMixpanel/HelloMixpanel/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ - (IBAction)sendPeopleRecord:(id)sender
// Note that the call to Mixpanel People identify: can come after properties have been set. We queue them until
// identify: is called and flush them at that time. That way, you can set properties before a user is logged in
// and identify them once you know their user ID.
[mixpanel.people identify:mixpanel.distinctId];
[mixpanel identify:mixpanel.distinctId];
}

@end
31 changes: 16 additions & 15 deletions HelloMixpanel/HelloMixpanelTests/HelloMixpanelTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ @interface MixpanelPeople (Test)

// get access to private members
@property(nonatomic,retain) NSMutableArray *unidentifiedQueue;
@property(nonatomic,copy) NSMutableArray *distinctId;

@end

Expand Down Expand Up @@ -242,7 +243,7 @@ - (void)testReset
self.mixpanel.nameTag = @"n1";
[self.mixpanel registerSuperProperties:p];
[self.mixpanel track:@"e1"];
[self.mixpanel.people identify:@"d1"];
[self.mixpanel identify:@"d1"];
[self.mixpanel.people set:p];
[self.mixpanel archive];

Expand Down Expand Up @@ -288,7 +289,7 @@ - (void)testArchive
self.mixpanel.nameTag = @"n1";
[self.mixpanel registerSuperProperties:p];
[self.mixpanel track:@"e1"];
[self.mixpanel.people identify:@"d1"];
[self.mixpanel identify:@"d1"];
[self.mixpanel.people set:p];

[self.mixpanel archive];
Expand Down Expand Up @@ -363,15 +364,15 @@ - (void)testPeopleIdentify
STAssertNotNil([p objectForKey:@"$ios_device_model"], @"missing $ios_device_model property");
STAssertNotNil([p objectForKey:@"$ios_version"], @"missing $ios_version property");
STAssertNotNil([p objectForKey:@"$ios_app_version"], @"missing $ios_app_version property");
[self.mixpanel.people identify:@"d1"];
[self.mixpanel identify:@"d1"];
STAssertEqualObjects(self.mixpanel.people.distinctId, @"d1", @"set people distinct id failed");
STAssertTrue(self.mixpanel.peopleQueue.count == 1, @"identify should move unidentified records to main queue");
STAssertTrue(self.mixpanel.people.unidentifiedQueue.count == 0, @"identify should move records from unidentified queue");
}

- (void)testPeopleAddPushDeviceToken
{
[self.mixpanel.people identify:@"d1"];
[self.mixpanel identify:@"d1"];
NSData *token = [@"0123456789abcdef" dataUsingEncoding:[NSString defaultCStringEncoding]];
[self.mixpanel.people addPushDeviceToken:token];
STAssertTrue(self.mixpanel.peopleQueue.count == 1, @"people records not queued");
Expand All @@ -388,7 +389,7 @@ - (void)testPeopleAddPushDeviceToken

- (void)testPeopleSet
{
[self.mixpanel.people identify:@"d1"];
[self.mixpanel identify:@"d1"];
NSDictionary *p = [NSDictionary dictionaryWithObject:@"a" forKey:@"p1"];
[self.mixpanel.people set:p];
STAssertTrue(self.mixpanel.peopleQueue.count == 1, @"people records not queued");
Expand All @@ -407,7 +408,7 @@ - (void)testPeopleSet

- (void)testPeopleSetOnce
{
[self.mixpanel.people identify:@"d1"];
[self.mixpanel identify:@"d1"];
NSDictionary *p = [NSDictionary dictionaryWithObject:@"a" forKey:@"p1"];
[self.mixpanel.people setOnce:p];
STAssertTrue(self.mixpanel.peopleQueue.count == 1, @"people records not queued");
Expand All @@ -426,7 +427,7 @@ - (void)testPeopleSetOnce

- (void)testPeopleSetReservedProperty
{
[self.mixpanel.people identify:@"d1"];
[self.mixpanel identify:@"d1"];
NSDictionary *p = [NSDictionary dictionaryWithObject:@"override" forKey:@"$ios_app_version"];
[self.mixpanel.people set:p];
NSDictionary *r = self.mixpanel.peopleQueue.lastObject;
Expand All @@ -436,7 +437,7 @@ - (void)testPeopleSetReservedProperty

- (void)testPeopleSetTo
{
[self.mixpanel.people identify:@"d1"];
[self.mixpanel identify:@"d1"];
[self.mixpanel.people set:@"p1" to:@"a"];
STAssertTrue(self.mixpanel.peopleQueue.count == 1, @"people records not queued");
NSDictionary *r = self.mixpanel.peopleQueue.lastObject;
Expand All @@ -453,7 +454,7 @@ - (void)testPeopleSetTo

- (void)testPeopleIncrement
{
[self.mixpanel.people identify:@"d1"];
[self.mixpanel identify:@"d1"];
NSDictionary *p = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:3] forKey:@"p1"];
[self.mixpanel.people increment:p];
STAssertTrue(self.mixpanel.peopleQueue.count == 1, @"people records not queued");
Expand All @@ -468,7 +469,7 @@ - (void)testPeopleIncrement

- (void)testPeopleIncrementBy
{
[self.mixpanel.people identify:@"d1"];
[self.mixpanel identify:@"d1"];
[self.mixpanel.people increment:@"p1" by:[NSNumber numberWithInt:3]];
STAssertTrue(self.mixpanel.peopleQueue.count == 1, @"people records not queued");
NSDictionary *r = self.mixpanel.peopleQueue.lastObject;
Expand All @@ -482,7 +483,7 @@ - (void)testPeopleIncrementBy

- (void)testPeopleDeleteUser
{
[self.mixpanel.people identify:@"d1"];
[self.mixpanel identify:@"d1"];
[self.mixpanel.people deleteUser];
STAssertTrue(self.mixpanel.peopleQueue.count == 1, @"people records not queued");
NSDictionary *r = self.mixpanel.peopleQueue.lastObject;
Expand All @@ -497,7 +498,7 @@ - (void)testMixpanelDelegate
{
self.mixpanel.delegate = self;
[self.mixpanel track:@"e1"];
[self.mixpanel.people identify:@"d1"];
[self.mixpanel identify:@"d1"];
[self.mixpanel.people set:@"p1" to:@"a"];
[self.mixpanel flush];
STAssertTrue(self.mixpanel.eventsQueue.count == 1, @"delegate should have stopped flush");
Expand Down Expand Up @@ -530,7 +531,7 @@ - (void)testNilArguments
STAssertNotNil([self.mixpanel currentSuperProperties], @"setting super properties to nil should have no effect");
STAssertTrue([[self.mixpanel currentSuperProperties] count] == 0, @"setting super properties to nil should have no effect");

[self.mixpanel.people identify:nil];
[self.mixpanel identify:nil];
STAssertNil(self.mixpanel.people.distinctId, @"people identify nil should make people distinct id nil");
STAssertThrows([self.mixpanel.people set:nil], @"should not take nil argument");
STAssertThrows([self.mixpanel.people set:nil to:@"a"], @"should not take nil argument");
Expand All @@ -544,7 +545,7 @@ - (void)testNilArguments

- (void)testPeopleTrackCharge
{
[self.mixpanel.people identify:@"d1"];
[self.mixpanel identify:@"d1"];

[self.mixpanel.people trackCharge:@25];
NSDictionary *r = self.mixpanel.peopleQueue.lastObject;
Expand Down Expand Up @@ -586,7 +587,7 @@ - (void)testPeopleTrackCharge

- (void)testPeopleClearCharges
{
[self.mixpanel.people identify:@"d1"];
[self.mixpanel identify:@"d1"];

[self.mixpanel.people clearCharges];
NSDictionary *r = self.mixpanel.peopleQueue.lastObject;
Expand Down
53 changes: 30 additions & 23 deletions Mixpanel/Mixpanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@
@discussion
A distinct ID is a string that uniquely identifies one of your users.
Typically, this is the user ID from your database. By default, we'll use a
hash of the MAC address of the device.
hash of the MAC address of the device. To change the current distinct ID,
use the <code>identify:</code> method.
*/
@property(nonatomic,setter=identify:,copy) NSString *distinctId;
@property(nonatomic,readonly,copy) NSString *distinctId;

/*!
@property
Expand Down Expand Up @@ -200,6 +201,33 @@
*/
- (id)initWithToken:(NSString *)apiToken andFlushInterval:(NSUInteger)flushInterval;

/*!
@property
@abstract
Sets the distinct ID of the current user.
@discussion
By default, Mixpanel will set the distinct ID to the device's iOS ID for
Advertising (IFA). The IFA depends on the the Ad Support framework, which is
only available in iOS 6 and later. For earlier platforms, we fallback to ODIN1
(see https://code.google.com/p/odinmobile/wiki/ODIN1).
For tracking events, you do not need to call <code>identify:</code> if you
want to use the default. However, <b>Mixpanel People always requires an
explicit call to <code>identify:</code></b>. If calls are made to
<code>set:</code>, <code>increment</code> or other <code>MixpanelPeople</code>
methods prior to calling <code>identify:</code>, then they are queued up and
flushed once <code>identify:</code> is called.
If you'd like to use the default distinct ID for Mixpanel People as well
(recommended), call <code>identify:</code> using the current distinct ID:
<code>[mixpanel identify:mixpanel.distinctId]</code>.
@param distinctId string that uniquely identifies the current user
*/
- (void)identify:(NSString *)distinctId;

/*!
@method
Expand Down Expand Up @@ -369,27 +397,6 @@
*/
@interface MixpanelPeople : NSObject

/*!
@property
@abstract
Sets the distinct ID for Mixpanel People calls.
@discussion
If calls are made to <code>set:</code>, <code>increment</code> or other
<code>MixpanelPeople</code> methods prior to calling <code>identify:</code>,
then they are queued up and flushed once <code>identify:</code> is called.
This method only affects calls to Mixpanel People. To change the distinct ID
of event tracking calls use the core Mixpanel @ref identify: method.
A distinct ID is a string string that uniquely identifies a user. Typically,
this is their user ID from your database.
@param distinctId string that uniquely identifies the current user
*/
@property(nonatomic,setter=identify:,copy) NSString *distinctId;

/*!
@method
Expand Down
46 changes: 26 additions & 20 deletions Mixpanel/Mixpanel.m
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@

@interface Mixpanel ()

@property(nonatomic,readwrite,retain) MixpanelPeople *people; // re-declare internally as readwrite
// re-declare internally as readwrite
@property(nonatomic,retain) MixpanelPeople *people;
@property(nonatomic,copy) NSString *distinctId;

@property(nonatomic,copy) NSString *apiToken;
@property(nonatomic,retain) NSMutableDictionary *superProperties;
@property(nonatomic,retain) NSTimer *timer;
Expand All @@ -75,6 +78,7 @@ @interface MixpanelPeople ()

@property(nonatomic,assign) Mixpanel *mixpanel;
@property(nonatomic,retain) NSMutableArray *unidentifiedQueue;
@property(nonatomic,copy) NSString *distinctId;

- (id)initWithMixpanel:(Mixpanel *)mixpanel;

Expand Down Expand Up @@ -410,6 +414,27 @@ - (id)initWithToken:(NSString *)apiToken andFlushInterval:(NSUInteger)flushInter
return self;
}

#pragma mark * Identity

- (void)identify:(NSString *)distinctId
{
@synchronized(self) {
self.distinctId = distinctId;
self.people.distinctId = distinctId;
if (distinctId != nil && distinctId.length != 0 && self.people.unidentifiedQueue.count > 0) {
for (NSMutableDictionary *r in self.people.unidentifiedQueue) {
[r setObject:distinctId forKey:@"$distinct_id"];
[self.peopleQueue addObject:r];
}
[self.people.unidentifiedQueue removeAllObjects];
}
if ([Mixpanel inBackground]) {
[self archiveProperties];
[self archivePeople];
}
}
}

#pragma mark * Tracking

- (NSString *)defaultDistinctId
Expand Down Expand Up @@ -1085,25 +1110,6 @@ - (id)initWithMixpanel:(Mixpanel *)mixpanel
return self;
}

- (void)identify:(NSString *)distinctId
{
@synchronized(self) {
[_distinctId autorelease];
_distinctId = [distinctId copy];
if (distinctId) {
for (NSMutableDictionary *r in self.unidentifiedQueue) {
[r setObject:distinctId forKey:@"$distinct_id"];
[self.mixpanel.peopleQueue addObject:r];
}
[self.unidentifiedQueue removeAllObjects];
}
if ([Mixpanel inBackground]) {
[self.mixpanel archiveProperties];
[self.mixpanel archivePeople];
}
}
}

- (void)addPushDeviceToken:(NSData *)deviceToken
{
const unsigned char *buffer = (const unsigned char *)[deviceToken bytes];
Expand Down

0 comments on commit 6194f18

Please sign in to comment.