@@ -181,7 +181,7 @@ - (RoktFrameworkType)mapMPWrapperSdkToRoktFrameworkType:(MPWrapperSdk)wrapperSdk
181181 if (filteredUser == nil && roktKit != nil ) {
182182 filteredUser = [[[MPKitAPI alloc ] init ] getCurrentUserWithKit: roktKit];
183183 }
184- NSDictionary <NSString *, NSString *> *mpAttributes = [filteredUser.userAttributes transformValuesToString ];
184+ NSDictionary <NSString *, NSString *> *mpAttributes = [self transformValuesToString: filteredUser.userAttributes];
185185 if (performMapping) {
186186 mpAttributes = [self mapAttributes: attributes filteredUser: filteredUser];
187187 }
@@ -197,6 +197,9 @@ - (RoktFrameworkType)mapMPWrapperSdkToRoktFrameworkType:(MPWrapperSdk)wrapperSdk
197197 // Add all known user identities to the attributes being passed to the Rokt SDK
198198 [self addIdentityAttributes: finalAtt filteredUser: filteredUser];
199199
200+ // Handle hashed email use case
201+ [self handleHashedEmail: finalAtt];
202+
200203 // The core SDK does not set sandbox on the user, but we must pass it to Rokt if provided
201204 NSString *sandboxKey = @" sandbox" ;
202205 if (attributes[sandboxKey] != nil ) {
@@ -206,6 +209,42 @@ - (RoktFrameworkType)mapMPWrapperSdkToRoktFrameworkType:(MPWrapperSdk)wrapperSdk
206209 return [self confirmSandboxAttribute: finalAtt];
207210}
208211
212+ + (NSDictionary <NSString *, NSString *> *)transformValuesToString : (NSDictionary <NSString *, id> * _Nullable)originalDictionary {
213+ __block NSMutableDictionary <NSString *, NSString *> *transformedDictionary = [[NSMutableDictionary alloc ] initWithCapacity: originalDictionary.count];
214+ Class NSStringClass = [NSString class ];
215+ Class NSNumberClass = [NSNumber class ];
216+
217+ [originalDictionary enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop) {
218+ if ([obj isKindOfClass: NSStringClass]) {
219+ transformedDictionary[key] = obj;
220+ } else if ([obj isKindOfClass: NSNumberClass]) {
221+ NSNumber *numberAttribute = (NSNumber *)obj;
222+
223+ if (numberAttribute == (void *)kCFBooleanFalse || numberAttribute == (void *)kCFBooleanTrue ) {
224+ transformedDictionary[key] = [numberAttribute boolValue ] ? @" true" : @" false" ;
225+ } else {
226+ transformedDictionary[key] = [numberAttribute stringValue ];
227+ }
228+ } else if ([obj isKindOfClass: [NSDate class ]]) {
229+ transformedDictionary[key] = [MPDateFormatter stringFromDateRFC3339: obj];
230+ } else if ([obj isKindOfClass: [NSData class ]] && [(NSData *)obj length ] > 0 ) {
231+ transformedDictionary[key] = [[NSString alloc ] initWithData: obj encoding: NSUTF8StringEncoding];
232+ } else if ([obj isKindOfClass: [NSDictionary class ]]) {
233+ transformedDictionary[key] = [obj description ];
234+ } else if ([obj isKindOfClass: [NSMutableDictionary class ]]) {
235+ transformedDictionary[key] = [obj description ];
236+ } else if ([obj isKindOfClass: [NSArray class ]]) {
237+ transformedDictionary[key] = [obj description ];
238+ } else if ([obj isKindOfClass: [NSMutableArray class ]]) {
239+ transformedDictionary[key] = [obj description ];
240+ } else if ([obj isKindOfClass: [NSNull class ]]) {
241+ transformedDictionary[key] = @" null" ;
242+ }
243+ }];
244+
245+ return transformedDictionary;
246+ }
247+
209248+ (NSDictionary <NSString *, NSString *> *)mapAttributes : (NSDictionary <NSString *, NSString *> * _Nullable)attributes filteredUser : (FilteredMParticleUser * _Nonnull)filteredUser {
210249 NSArray <NSDictionary <NSString *, NSString *> *> *attributeMap = nil ;
211250
@@ -273,7 +312,7 @@ - (RoktFrameworkType)mapMPWrapperSdkToRoktFrameworkType:(MPWrapperSdk)wrapperSdk
273312 }
274313 }
275314
276- return [mappedAttributes transformValuesToString ];
315+ return [self transformValuesToString: mappedAttributes ];
277316 } else {
278317 return attributes;
279318 }
@@ -293,6 +332,27 @@ + (void)addIdentityAttributes:(NSMutableDictionary<NSString *, NSString *> * _Nu
293332 }
294333}
295334
335+ + (void )handleHashedEmail : (NSMutableDictionary <NSString *, NSString *> * _Nullable)attributes {
336+ NSString *emailKey = [MPKitRokt stringForIdentityType: MPIdentityEmail];
337+ NSString *otherKey = [MPKitRokt stringForIdentityType: MPIdentityOther];
338+ NSString *hashedEmailValue = attributes[@" emailsha256" ];
339+
340+ // Remove email and other is hashed vlaue already set
341+ if (hashedEmailValue != nil ) {
342+ [attributes removeObjectForKey: emailKey];
343+ [attributes removeObjectForKey: otherKey];
344+ }
345+
346+ NSString *otherValue = attributes[otherKey];
347+
348+ // Remove email and replace key on other if it's set
349+ if (otherValue != nil ) {
350+ [attributes removeObjectForKey: emailKey];
351+ attributes[@" emailsha256" ] = otherValue;
352+ [attributes removeObjectForKey: otherKey];
353+ }
354+ }
355+
296356+ (RoktConfig *)convertMPRoktConfig : (MPRoktConfig *)mpRoktConfig {
297357 if (mpRoktConfig != nil ) {
298358 Builder *builder = [[Builder alloc ] init ];
0 commit comments