Skip to content

Commit ee4e7fc

Browse files
feat: Map Selected Identity to Emailsha256 (#29)
* feat: Map Selected Identity to Emailsha256
1 parent 1696f39 commit ee4e7fc

4 files changed

Lines changed: 158 additions & 84 deletions

File tree

mParticle-Rokt-Swift/MPRoktLayout.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,10 @@ public class MPRoktLayout {
5353
}
5454
let email = attributes?["email"]
5555
let hashedEmail = attributes?["emailsha256"]
56+
let hashedEmailIdentity = MPKitRokt.getHashedEmailUserIdentityType()
5657

5758
let userEmailIdentity = user.identities[NSNumber(value: MPIdentity.email.rawValue)]
58-
let userHashedEmailIdentity = user.identities[NSNumber(value: MPIdentity.other.rawValue)]
59+
let userHashedEmailIdentity = user.identities[hashedEmailIdentity]
5960

6061
let emailMismatch = email != nil && email != userEmailIdentity
6162
let hashedEmailMismatch = hashedEmail != nil && hashedEmail != userHashedEmailIdentity
@@ -69,7 +70,7 @@ public class MPRoktLayout {
6970
print("The existing hashed email on the user (\(userHashedEmailIdentity ?? "nil")) does not match the email passed in to `selectPlacements:` (\(hashedEmail ?? "nil")). Please remember to sync the email identity to mParticle as soon as you receive it. We will now identify the user before creating the layout")
7071
}
7172

72-
syncIdentities(user: user, email: email, hashedEmail: hashedEmail, completion: completion)
73+
syncIdentities(user: user, email: email, hashedEmail: hashedEmail, hashedEmailKey: hashedEmailIdentity, completion: completion)
7374
} else {
7475
completion()
7576
}
@@ -79,11 +80,12 @@ public class MPRoktLayout {
7980
user: MParticleUser,
8081
email: String?,
8182
hashedEmail: String?,
83+
hashedEmailKey: NSNumber,
8284
completion: @escaping () -> Void
8385
) {
8486
let identityRequest = MPIdentityApiRequest(user: user)
8587
identityRequest.setIdentity(email, identityType: .email)
86-
identityRequest.setIdentity(hashedEmail, identityType: .other)
88+
identityRequest.setIdentity(hashedEmail, identityType: MPIdentity(rawValue: hashedEmailKey.uintValue) ?? .other)
8789

8890
mparticle.identity.identify(identityRequest) {apiResult, error in
8991
if let error = error {

mParticle-Rokt/MPKitRokt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@
1717
@property (nonatomic, unsafe_unretained, readonly) BOOL started;
1818

1919
+ (NSDictionary<NSString *, NSString *> * _Nonnull)prepareAttributes:(NSDictionary<NSString *, NSString *> * _Nonnull)attributes filteredUser:(FilteredMParticleUser * _Nullable)filteredUser performMapping:(BOOL)performMapping;
20+
+ (NSNumber * _Nonnull)getRoktHashedEmailUserIdentityType;
2021

2122
@end

mParticle-Rokt/MPKitRokt.m

Lines changed: 84 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
NSString * const MPKitRoktErrorDomain = @"com.mparticle.kits.rokt";
77
NSString * const MPKitRoktErrorMessageKey = @"mParticle-Rokt Error";
88
NSString * const kMPPlacementAttributesMapping = @"placementAttributesMapping";
9+
NSString * const kMPHashedEmailUserIdentityType = @"hashedEmailUserIdentityType";
10+
NSInteger const kMPRoktKitCode = 181;
11+
912
static __weak MPKitRokt *roktKit = nil;
1013

1114
@interface MPKitRokt () <MPKitProtocol>
@@ -20,7 +23,7 @@ @implementation MPKitRokt
2023
mParticle will supply a unique kit code for you. Please contact our team
2124
*/
2225
+ (NSNumber *)kitCode {
23-
return @181; // Replace with the actual kit code assigned by mParticle
26+
return @(kMPRoktKitCode); // Replace with the actual kit code assigned by mParticle
2427
}
2528

2629
+ (void)load {
@@ -251,7 +254,7 @@ - (RoktFrameworkType)mapMPWrapperSdkToRoktFrameworkType:(MPWrapperSdk)wrapperSdk
251254
NSArray<NSDictionary *> *kitConfigs = [MParticle sharedInstance].kitContainer_PRIVATE.originalConfig.copy;
252255
NSDictionary *roktKitConfig;
253256
for (NSDictionary *kitConfig in kitConfigs) {
254-
if (kitConfig[@"id"] != nil && [kitConfig[@"id"] integerValue] == 181) {
257+
if (kitConfig[@"id"] != nil && [kitConfig[@"id"] integerValue] == kMPRoktKitCode) {
255258
roktKitConfig = kitConfig;
256259
}
257260
}
@@ -361,86 +364,86 @@ + (RoktConfig *)convertMPRoktConfig:(MPRoktConfig *)mpRoktConfig {
361364
}
362365

363366
+ (NSString *)stringForIdentityType:(MPIdentity)identityType {
364-
switch (identityType) {
365-
case MPIdentityCustomerId:
366-
return @"customerid";
367-
368-
case MPIdentityEmail:
369-
return @"email";
370-
371-
case MPIdentityFacebook:
372-
return @"facebook";
373-
374-
case MPIdentityFacebookCustomAudienceId:
375-
return @"facebookcustomaudienceid";
376-
377-
case MPIdentityGoogle:
378-
return @"google";
379-
380-
case MPIdentityMicrosoft:
381-
return @"microsoft";
382-
383-
case MPIdentityOther:
384-
// As of 7/30/2025, "MPIdentityOther" is used by Rokt customers to identify based off hashed email
385-
return @"emailsha256";
386-
387-
case MPIdentityTwitter:
388-
return @"twitter";
389-
390-
case MPIdentityYahoo:
391-
return @"yahoo";
392-
393-
case MPIdentityOther2:
394-
return @"other2";
395-
396-
case MPIdentityOther3:
397-
return @"other3";
398-
399-
case MPIdentityOther4:
400-
return @"other4";
401-
402-
case MPIdentityOther5:
403-
return @"other5";
404-
405-
case MPIdentityOther6:
406-
return @"other6";
407-
408-
case MPIdentityOther7:
409-
return @"other7";
410-
411-
case MPIdentityOther8:
412-
return @"other8";
413-
414-
case MPIdentityOther9:
415-
return @"other9";
416-
417-
case MPIdentityOther10:
418-
return @"other10";
419-
420-
case MPIdentityMobileNumber:
421-
return @"mobile_number";
422-
423-
case MPIdentityPhoneNumber2:
424-
return @"phone_number_2";
425-
426-
case MPIdentityPhoneNumber3:
427-
return @"phone_number_3";
428-
429-
case MPIdentityIOSAdvertiserId:
430-
return @"ios_idfa";
431-
432-
case MPIdentityIOSVendorId:
433-
return @"ios_idfv";
434-
435-
case MPIdentityPushToken:
436-
return @"push_token";
437-
438-
case MPIdentityDeviceApplicationStamp:
439-
return @"device_application_stamp";
440-
441-
default:
442-
return nil;
367+
NSNumber *hashedEmailIdentity = [MPKitRokt getRoktHashedEmailUserIdentityType];
368+
369+
if (hashedEmailIdentity.unsignedIntValue == identityType) {
370+
return @"emailsha256";
371+
}
372+
373+
NSDictionary<NSNumber *, NSString *> *identityStrings = @{@(MPIdentityCustomerId): @"customerid",
374+
@(MPIdentityEmail): @"email",
375+
@(MPIdentityFacebook): @"facebook",
376+
@(MPIdentityFacebookCustomAudienceId): @"facebookcustomaudienceid",
377+
@(MPIdentityGoogle): @"google",
378+
@(MPIdentityMicrosoft): @"microsoft",
379+
@(MPIdentityOther): @"other",
380+
@(MPIdentityTwitter): @"twitter",
381+
@(MPIdentityYahoo): @"yahoo",
382+
@(MPIdentityOther2): @"other2",
383+
@(MPIdentityOther3): @"other3",
384+
@(MPIdentityOther4): @"other4",
385+
@(MPIdentityOther5): @"other5",
386+
@(MPIdentityOther6): @"other6",
387+
@(MPIdentityOther7): @"other7",
388+
@(MPIdentityOther8): @"other8",
389+
@(MPIdentityOther9): @"other9",
390+
@(MPIdentityOther10): @"other10",
391+
@(MPIdentityMobileNumber): @"mobile_number",
392+
@(MPIdentityPhoneNumber2): @"phone_number_2",
393+
@(MPIdentityPhoneNumber3): @"phone_number_3",
394+
@(MPIdentityIOSAdvertiserId): @"ios_idfa",
395+
@(MPIdentityIOSVendorId): @"ios_idfv",
396+
@(MPIdentityPushToken): @"push_token",
397+
@(MPIdentityDeviceApplicationStamp): @"device_application_stamp"};
398+
399+
return identityStrings[@(identityType)];
400+
}
401+
402+
+ (NSNumber *)identityTypeForString:(NSString *)identityString {
403+
NSDictionary<NSString *, NSNumber *> *identityNumbers = @{@"customerid": @(MPIdentityCustomerId),
404+
@"email": @(MPIdentityEmail),
405+
@"facebook": @(MPIdentityFacebook),
406+
@"facebookcustomaudienceid": @(MPIdentityFacebookCustomAudienceId),
407+
@"google": @(MPIdentityGoogle),
408+
@"microsoft": @(MPIdentityMicrosoft),
409+
@"other": @(MPIdentityOther),
410+
@"twitter": @(MPIdentityTwitter),
411+
@"yahoo": @(MPIdentityYahoo),
412+
@"other2": @(MPIdentityOther2),
413+
@"other3": @(MPIdentityOther3),
414+
@"other4": @(MPIdentityOther4),
415+
@"other5": @(MPIdentityOther5),
416+
@"other6": @(MPIdentityOther6),
417+
@"other7": @(MPIdentityOther7),
418+
@"other8": @(MPIdentityOther8),
419+
@"other9": @(MPIdentityOther9),
420+
@"other10": @(MPIdentityOther10),
421+
@"mobile_number": @(MPIdentityMobileNumber),
422+
@"phone_number_2": @(MPIdentityPhoneNumber2),
423+
@"phone_number_3": @(MPIdentityPhoneNumber3),
424+
@"ios_idfa": @(MPIdentityIOSAdvertiserId),
425+
@"ios_idfv": @(MPIdentityIOSVendorId),
426+
@"push_token": @(MPIdentityPushToken),
427+
@"device_application_stamp": @(MPIdentityDeviceApplicationStamp)};
428+
429+
return identityNumbers[identityString];
430+
}
431+
432+
+ (NSNumber *)getRoktHashedEmailUserIdentityType {
433+
// Get the kit configuration
434+
NSArray<NSDictionary *> *kitConfigs = [MParticle sharedInstance].kitContainer_PRIVATE.originalConfig.copy;
435+
NSDictionary *roktKitConfig;
436+
for (NSDictionary *kitConfig in kitConfigs) {
437+
if (kitConfig[@"id"] != nil && [kitConfig[@"id"] integerValue] == kMPRoktKitCode) {
438+
roktKitConfig = kitConfig;
439+
}
443440
}
441+
442+
// Get the string representing which identity to use and convert it to the key (NSNumber)
443+
NSString *hashedIdentityTypeString = roktKitConfig[kMPHashedEmailUserIdentityType];
444+
NSNumber *hashedIdentityTypeNumber = [MPKitRokt identityTypeForString:hashedIdentityTypeString.lowercaseString];
445+
446+
return hashedIdentityTypeNumber != nil ? hashedIdentityTypeNumber : @(MPIdentityOther);
444447
}
445448

446449
- (MPKitExecStatus *)purchaseFinalized:(NSString *)placementId catalogItemId:(NSString *)catalogItemId success:(NSNumber *)success {

mParticle_RoktTests/mParticle_RoktTests.m

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ + (void)addIdentityAttributes:(NSMutableDictionary<NSString *, NSString *> * _Nu
2424

2525
+ (void)handleHashedEmail:(NSMutableDictionary<NSString *, NSString *> * _Nullable)attributes;
2626

27+
+ (NSNumber *)getRoktHashedEmailUserIdentityType;
28+
2729
+ (RoktConfig *)convertMPRoktConfig:(MPRoktConfig *)mpRoktConfig;
2830

2931
+ (NSDictionary<NSString *, NSString *> *)transformValuesToString:(NSDictionary<NSString *, id> * _Nullable)originalDictionary;
@@ -329,6 +331,72 @@ - (void)testAddIdentityAttributesWithExistingAttributes {
329331
XCTAssertEqualObjects(passedAttributes[@"device_application_stamp"], @"Test DAS");
330332
}
331333

334+
- (void)testAddIdentityAttributesWithExistingAttributesAndOther {
335+
NSMutableDictionary<NSString *, NSString *> *passedAttributes = [[NSMutableDictionary alloc] init];
336+
[passedAttributes setObject:@"bar" forKey:@"foo"];
337+
NSDictionary<NSNumber *, NSString *> *testIdentities = @{@(MPIdentityCustomerId): @"testCustomerID",
338+
@(MPIdentityEmail): @"testEmail@gmail.com",
339+
@(MPIdentityFacebook): @"testFacebook",
340+
@(MPIdentityFacebookCustomAudienceId): @"testCustomAudienceID",
341+
@(MPIdentityGoogle): @"testGoogle",
342+
@(MPIdentityMicrosoft): @"testMicrosoft",
343+
@(MPIdentityOther): @"testOther",
344+
@(MPIdentityTwitter): @"testTwitter",
345+
@(MPIdentityYahoo): @"testYahoo",
346+
@(MPIdentityOther2): @"testOther2",
347+
@(MPIdentityOther3): @"testOther3",
348+
@(MPIdentityOther4): @"testOther4",
349+
@(MPIdentityOther5): @"testOther5",
350+
@(MPIdentityOther6): @"testOther6",
351+
@(MPIdentityOther7): @"testOther7",
352+
@(MPIdentityOther8): @"testOther8",
353+
@(MPIdentityOther9): @"testOther9",
354+
@(MPIdentityOther10): @"testOther10",
355+
@(MPIdentityMobileNumber): @"1(234)-567-8910",
356+
@(MPIdentityPhoneNumber2): @"1(234)-567-2222",
357+
@(MPIdentityPhoneNumber3): @"1(234)-567-3333",
358+
@(MPIdentityIOSAdvertiserId): @"testAdvertID",
359+
@(MPIdentityIOSVendorId): @"testVendorID",
360+
@(MPIdentityPushToken): @"testPushToken",
361+
@(MPIdentityDeviceApplicationStamp): @"Test DAS"};
362+
363+
FilteredMParticleUser *filteredUser = [[FilteredMParticleUser alloc] init];
364+
id mockfilteredUser = OCMPartialMock(filteredUser);
365+
[[[mockfilteredUser stub] andReturn:testIdentities] userIdentities];
366+
id mockMPKitRoktClass = OCMClassMock([MPKitRokt class]);
367+
[[[mockMPKitRoktClass stub] andReturn:@(MPIdentityOther4)] getRoktHashedEmailUserIdentityType];
368+
369+
[MPKitRokt addIdentityAttributes:passedAttributes filteredUser:filteredUser];
370+
371+
XCTAssertEqualObjects(passedAttributes[@"foo"], @"bar");
372+
XCTAssertEqualObjects(passedAttributes[@"customerid"], @"testCustomerID");
373+
XCTAssertEqualObjects(passedAttributes[@"email"], @"testEmail@gmail.com");
374+
XCTAssertEqualObjects(passedAttributes[@"facebook"], @"testFacebook");
375+
XCTAssertEqualObjects(passedAttributes[@"facebookcustomaudienceid"], @"testCustomAudienceID");
376+
XCTAssertEqualObjects(passedAttributes[@"google"], @"testGoogle");
377+
XCTAssertEqualObjects(passedAttributes[@"microsoft"], @"testMicrosoft");
378+
XCTAssertEqualObjects(passedAttributes[@"other"], @"testOther");
379+
XCTAssertEqualObjects(passedAttributes[@"emailsha256"], @"testOther4");
380+
XCTAssertEqualObjects(passedAttributes[@"twitter"], @"testTwitter");
381+
XCTAssertEqualObjects(passedAttributes[@"yahoo"], @"testYahoo");
382+
XCTAssertEqualObjects(passedAttributes[@"other2"], @"testOther2");
383+
XCTAssertEqualObjects(passedAttributes[@"other3"], @"testOther3");
384+
XCTAssertNil(passedAttributes[@"other4"]);
385+
XCTAssertEqualObjects(passedAttributes[@"other5"], @"testOther5");
386+
XCTAssertEqualObjects(passedAttributes[@"other6"], @"testOther6");
387+
XCTAssertEqualObjects(passedAttributes[@"other7"], @"testOther7");
388+
XCTAssertEqualObjects(passedAttributes[@"other8"], @"testOther8");
389+
XCTAssertEqualObjects(passedAttributes[@"other9"], @"testOther9");
390+
XCTAssertEqualObjects(passedAttributes[@"other10"], @"testOther10");
391+
XCTAssertEqualObjects(passedAttributes[@"mobile_number"], @"1(234)-567-8910");
392+
XCTAssertEqualObjects(passedAttributes[@"phone_number_2"], @"1(234)-567-2222");
393+
XCTAssertEqualObjects(passedAttributes[@"phone_number_3"], @"1(234)-567-3333");
394+
XCTAssertEqualObjects(passedAttributes[@"ios_idfa"], @"testAdvertID");
395+
XCTAssertEqualObjects(passedAttributes[@"ios_idfv"], @"testVendorID");
396+
XCTAssertEqualObjects(passedAttributes[@"push_token"], @"testPushToken");
397+
XCTAssertEqualObjects(passedAttributes[@"device_application_stamp"], @"Test DAS");
398+
}
399+
332400
- (void)testConvertMPRoktConfig {
333401
MPRoktConfig *mpConfig = [[MPRoktConfig alloc] init];
334402
mpConfig.colorMode = MPColorModeDark;

0 commit comments

Comments
 (0)