|
6 | 6 | NSString * const kMPRemoteConfigUserAttributeFilter = @"ua"; |
7 | 7 | NSString * const MPKitRoktErrorDomain = @"com.mparticle.kits.rokt"; |
8 | 8 | NSString * const MPKitRoktErrorMessageKey = @"mParticle-Rokt Error"; |
| 9 | +NSString * const kMPPlacementAttributesMapping = @"placementAttributesMapping"; |
| 10 | +static __weak MPKitRokt *roktKit = nil; |
9 | 11 |
|
10 | 12 | @interface MPKitRokt () <MPKitProtocol> |
11 | 13 |
|
@@ -42,6 +44,7 @@ - (MPKitExecStatus *)didFinishLaunchingWithConfiguration:(NSDictionary *)configu |
42 | 44 | } |
43 | 45 |
|
44 | 46 | _configuration = configuration; |
| 47 | + roktKit = self; |
45 | 48 |
|
46 | 49 | NSString *sdkVersion = [MParticle sharedInstance].version; |
47 | 50 | // https://go.mparticle.com/work/SQDSDKS-7379 |
@@ -93,23 +96,7 @@ - (MPKitExecStatus *)executeWithIdentifier:(NSString * _Nullable)identifier |
93 | 96 | config:(MPRoktConfig * _Nullable)mpRoktConfig |
94 | 97 | callbacks:(MPRoktEventCallback * _Nullable)callbacks |
95 | 98 | filteredUser:(FilteredMParticleUser * _Nonnull)filteredUser { |
96 | | - NSDictionary<NSString *, NSString *> *mpAttributes = [filteredUser.userAttributes transformValuesToString]; |
97 | | - NSMutableDictionary<NSString *, NSString *> *finalAtt = [[NSMutableDictionary alloc] init]; |
98 | | - [finalAtt addEntriesFromDictionary:mpAttributes]; |
99 | | - |
100 | | - // Add MPID to the attributes being passed to the Rokt SDK |
101 | | - if (filteredUser.userId.stringValue != nil) { |
102 | | - [finalAtt addEntriesFromDictionary:@{@"mpid": filteredUser.userId.stringValue}]; |
103 | | - } |
104 | | - |
105 | | - // Add all known user identities to the attributes being passed to the Rokt SDK |
106 | | - [self addIdentityAttributes:finalAtt filteredUser:filteredUser]; |
107 | | - |
108 | | - // The core SDK does not set sandbox on the user, but we must pass it to Rokt if provided |
109 | | - NSString *sandboxKey = @"sandbox"; |
110 | | - if (attributes[sandboxKey] != nil) { |
111 | | - [finalAtt addEntriesFromDictionary:@{sandboxKey: attributes[sandboxKey]}]; |
112 | | - } |
| 99 | + NSDictionary<NSString *, NSString *> *finalAtt = [MPKitRokt prepareAttributes:attributes filteredUser:filteredUser performMapping:NO]; |
113 | 100 |
|
114 | 101 | //Convert MPRoktConfig to RoktConfig |
115 | 102 | RoktConfig *roktConfig = [MPKitRokt convertMPRoktConfig:mpRoktConfig]; |
@@ -171,7 +158,128 @@ - (RoktFrameworkType)mapMPWrapperSdkToRoktFrameworkType:(MPWrapperSdk)wrapperSdk |
171 | 158 | return safePlacements; |
172 | 159 | } |
173 | 160 |
|
174 | | -- (void)addIdentityAttributes:(NSMutableDictionary<NSString *, NSString *> * _Nullable)attributes filteredUser:(FilteredMParticleUser * _Nonnull)filteredUser { |
| 161 | ++ (NSDictionary<NSString *, NSString *> *)confirmSandboxAttribute:(NSDictionary<NSString *, NSString *> * _Nullable)attributes { |
| 162 | + NSMutableDictionary<NSString *, NSString *> *finalAttributes = attributes.mutableCopy; |
| 163 | + NSString *sandboxKey = @"sandbox"; |
| 164 | + |
| 165 | + // Determine the value of the sandbox attribute based off the current environment |
| 166 | + NSString *sandboxValue = ([[MParticle sharedInstance] environment] == MPEnvironmentDevelopment) ? @"true" : @"false"; |
| 167 | + |
| 168 | + if (finalAttributes != nil) { |
| 169 | + // Only set sandbox if it`s not set by the client |
| 170 | + if (![finalAttributes.allKeys containsObject:sandboxKey]) { |
| 171 | + finalAttributes[sandboxKey] = sandboxValue; |
| 172 | + } |
| 173 | + } else { |
| 174 | + finalAttributes = [[NSMutableDictionary alloc] initWithDictionary:@{sandboxKey: sandboxValue}]; |
| 175 | + } |
| 176 | + |
| 177 | + return finalAttributes; |
| 178 | +} |
| 179 | + |
| 180 | ++ (NSDictionary<NSString *, NSString *> * _Nonnull)prepareAttributes:(NSDictionary<NSString *, NSString *> * _Nonnull)attributes filteredUser:(FilteredMParticleUser * _Nullable)filteredUser performMapping:(BOOL)performMapping { |
| 181 | + if (filteredUser == nil && roktKit != nil) { |
| 182 | + filteredUser = [[[MPKitAPI alloc] init] getCurrentUserWithKit:roktKit]; |
| 183 | + } |
| 184 | + NSDictionary<NSString *, NSString *> *mpAttributes = [filteredUser.userAttributes transformValuesToString]; |
| 185 | + if (performMapping) { |
| 186 | + mpAttributes = [self mapAttributes:attributes filteredUser:filteredUser]; |
| 187 | + } |
| 188 | + |
| 189 | + NSMutableDictionary<NSString *, NSString *> *finalAtt = [[NSMutableDictionary alloc] init]; |
| 190 | + [finalAtt addEntriesFromDictionary:mpAttributes]; |
| 191 | + |
| 192 | + // Add MPID to the attributes being passed to the Rokt SDK |
| 193 | + if (filteredUser.userId.stringValue != nil) { |
| 194 | + [finalAtt addEntriesFromDictionary:@{@"mpid": filteredUser.userId.stringValue}]; |
| 195 | + } |
| 196 | + |
| 197 | + // Add all known user identities to the attributes being passed to the Rokt SDK |
| 198 | + [self addIdentityAttributes:finalAtt filteredUser:filteredUser]; |
| 199 | + |
| 200 | + // The core SDK does not set sandbox on the user, but we must pass it to Rokt if provided |
| 201 | + NSString *sandboxKey = @"sandbox"; |
| 202 | + if (attributes[sandboxKey] != nil) { |
| 203 | + [finalAtt addEntriesFromDictionary:@{sandboxKey: attributes[sandboxKey]}]; |
| 204 | + } |
| 205 | + |
| 206 | + return [self confirmSandboxAttribute:finalAtt]; |
| 207 | +} |
| 208 | + |
| 209 | ++ (NSDictionary<NSString *, NSString *> *)mapAttributes:(NSDictionary<NSString *, NSString *> * _Nullable)attributes filteredUser:(FilteredMParticleUser * _Nonnull)filteredUser { |
| 210 | + NSArray<NSDictionary<NSString *, NSString *> *> *attributeMap = nil; |
| 211 | + |
| 212 | + // Get the kit configuration |
| 213 | + NSArray<NSDictionary *> *kitConfigs = [MParticle sharedInstance].kitContainer_PRIVATE.originalConfig.copy; |
| 214 | + NSDictionary *roktKitConfig; |
| 215 | + for (NSDictionary *kitConfig in kitConfigs) { |
| 216 | + if (kitConfig[@"id"] != nil && [kitConfig[@"id"] integerValue] == 181) { |
| 217 | + roktKitConfig = kitConfig; |
| 218 | + } |
| 219 | + } |
| 220 | + |
| 221 | + // Return nil if no Rokt Kit configuration found |
| 222 | + if (!roktKitConfig) { |
| 223 | + return attributes; |
| 224 | + } |
| 225 | + |
| 226 | + // Get the placement attributes map |
| 227 | + NSString *strAttributeMap; |
| 228 | + NSData *dataAttributeMap; |
| 229 | + // Rokt Kit is available though there may not be an attribute map |
| 230 | + attributeMap = @[]; |
| 231 | + if (roktKitConfig[kMPPlacementAttributesMapping] != [NSNull null]) { |
| 232 | + strAttributeMap = [roktKitConfig[kMPPlacementAttributesMapping] stringByRemovingPercentEncoding]; |
| 233 | + dataAttributeMap = [strAttributeMap dataUsingEncoding:NSUTF8StringEncoding]; |
| 234 | + } |
| 235 | + |
| 236 | + if (dataAttributeMap != nil) { |
| 237 | + // Convert it to an array of dictionaries |
| 238 | + NSError *error = nil; |
| 239 | + |
| 240 | + @try { |
| 241 | + attributeMap = [NSJSONSerialization JSONObjectWithData:dataAttributeMap options:kNilOptions error:&error]; |
| 242 | + } @catch (NSException *exception) { |
| 243 | + } |
| 244 | + |
| 245 | + if (attributeMap && !error) { |
| 246 | + NSLog(@"%@", attributeMap); |
| 247 | + } else { |
| 248 | + NSLog(@"%@", error); |
| 249 | + } |
| 250 | + } |
| 251 | + |
| 252 | + if (attributeMap) { |
| 253 | + NSMutableDictionary *mappedAttributes = attributes.mutableCopy; |
| 254 | + for (NSDictionary<NSString *, NSString *> *map in attributeMap) { |
| 255 | + NSString *mapFrom = map[@"map"]; |
| 256 | + NSString *mapTo = map[@"value"]; |
| 257 | + if (mappedAttributes[mapFrom]) { |
| 258 | + NSString * value = mappedAttributes[mapFrom]; |
| 259 | + [mappedAttributes removeObjectForKey:mapFrom]; |
| 260 | + mappedAttributes[mapTo] = value; |
| 261 | + } |
| 262 | + } |
| 263 | + for (NSString *key in mappedAttributes) { |
| 264 | + if (![key isEqual:@"sandbox"]) { |
| 265 | + [[MParticle sharedInstance].identity.currentUser setUserAttribute:key value:mappedAttributes[key]]; |
| 266 | + } |
| 267 | + } |
| 268 | + |
| 269 | + // Add userAttributes to the attributes sent to Rokt |
| 270 | + for (NSString *uaKey in filteredUser.userAttributes) { |
| 271 | + if (![mappedAttributes.allKeys containsObject:uaKey]) { |
| 272 | + mappedAttributes[uaKey] = filteredUser.userAttributes[uaKey]; |
| 273 | + } |
| 274 | + } |
| 275 | + |
| 276 | + return [mappedAttributes transformValuesToString]; |
| 277 | + } else { |
| 278 | + return attributes; |
| 279 | + } |
| 280 | +} |
| 281 | + |
| 282 | ++ (void)addIdentityAttributes:(NSMutableDictionary<NSString *, NSString *> * _Nullable)attributes filteredUser:(FilteredMParticleUser * _Nonnull)filteredUser { |
175 | 283 | NSMutableDictionary<NSString *, NSString *> *identityAttributes = [[NSMutableDictionary alloc] init]; |
176 | 284 | for (NSNumber *identityNumberKey in filteredUser.userIdentities) { |
177 | 285 | NSString *identityStringKey = [MPKitRokt stringForIdentityType:identityNumberKey.unsignedIntegerValue]; |
|
0 commit comments