1212#import " MPIConstants.h"
1313#import " MPIdentityDTO.h"
1414
15+ // Constants for kit configuration keys
16+ static NSString * const kMPKitConfigurationIdKey = @" id" ;
17+ static NSString * const kMPAttributeMappingSourceKey = @" map" ;
18+ static NSString * const kMPAttributeMappingDestinationKey = @" value" ;
19+
20+ // Rokt attribute keys
21+ static NSString * const kMPRoktAttributeKeySandbox = @" sandbox" ;
22+
23+ // Rokt kit identifier
24+ static const NSInteger kMPRoktKitId = 181 ;
25+
1526@interface MParticle ()
1627
1728+ (dispatch_queue_t )messageQueue ;
@@ -29,11 +40,25 @@ @implementation MPRoktConfig
2940
3041@implementation MPRokt
3142
43+ // / Displays a Rokt ad placement with the specified identifier and user attributes.
44+ // / This is a convenience method that calls the full selectPlacements method with nil for optional parameters.
45+ // / - Parameters:
46+ // / - identifier: The Rokt placement identifier configured in the Rokt dashboard (e.g., "checkout_confirmation")
47+ // / - attributes: Optional dictionary of user attributes to pass to Rokt (e.g., email, firstName, etc.)
3248- (void )selectPlacements : (NSString *)identifier
3349 attributes : (NSDictionary <NSString *, NSString *> * _Nullable)attributes {
3450 [self selectPlacements: identifier attributes: attributes embeddedViews: nil config: nil callbacks: nil ];
3551}
3652
53+ // / Displays a Rokt ad placement with full configuration options.
54+ // / This method handles user identity synchronization, attribute mapping, and forwards the request to the Rokt Kit.
55+ // / Device identifiers (IDFA/IDFV) are automatically added if available.
56+ // / - Parameters:
57+ // / - identifier: The Rokt placement identifier configured in the Rokt dashboard
58+ // / - attributes: Optional dictionary of user attributes (email, firstName, etc.). Attributes will be mapped according to dashboard configuration.
59+ // / - embeddedViews: Optional dictionary mapping placement identifiers to embedded view containers for inline placements
60+ // / - config: Optional Rokt configuration object (e.g., for dark mode or custom styling)
61+ // / - callbacks: Optional callback handlers for Rokt events (selection, display, completion, etc.)
3762- (void )selectPlacements : (NSString *)identifier
3863 attributes : (NSDictionary <NSString *, NSString *> * _Nullable)attributes
3964 embeddedViews : (NSDictionary <NSString *, MPRoktEmbeddedView *> * _Nullable)embeddedViews
@@ -49,16 +74,16 @@ - (void)selectPlacements:(NSString *)identifier
4974 if (attributeMap) {
5075 NSMutableDictionary *mappedAttributes = attributes.mutableCopy ;
5176 for (NSDictionary <NSString *, NSString *> *map in attributeMap) {
52- NSString *mapFrom = map[@" map " ];
53- NSString *mapTo = map[@" value " ];
77+ NSString *mapFrom = map[kMPAttributeMappingSourceKey ];
78+ NSString *mapTo = map[kMPAttributeMappingDestinationKey ];
5479 if (mappedAttributes[mapFrom]) {
5580 NSString * value = mappedAttributes[mapFrom];
5681 [mappedAttributes removeObjectForKey: mapFrom];
5782 mappedAttributes[mapTo] = value;
5883 }
5984 }
6085 for (NSString *key in mappedAttributes) {
61- if (![key isEqual: @" sandbox " ]) {
86+ if (![key isEqual: kMPRoktAttributeKeySandbox ]) {
6287 [resolvedUser setUserAttribute: key value: mappedAttributes[key]];
6388 }
6489 }
@@ -86,6 +111,12 @@ - (void)selectPlacements:(NSString *)identifier
86111 }];
87112}
88113
114+ // / Notifies Rokt that a purchase from a placement offer has been finalized.
115+ // / Call this method to inform Rokt about the completion status of an offer purchase initiated from a placement.
116+ // / - Parameters:
117+ // / - placementId: The identifier of the placement where the offer was displayed
118+ // / - catalogItemId: The identifier of the catalog item that was purchased
119+ // / - success: Whether the purchase was successful (YES) or failed (NO)
89120- (void )purchaseFinalized : (NSString * _Nonnull)placementId catalogItemId : (NSString * _Nonnull)catalogItemId success : (BOOL )success {
90121 dispatch_async (dispatch_get_main_queue (), ^{
91122 // Forwarding call to kits
@@ -103,6 +134,11 @@ - (void)purchaseFinalized:(NSString * _Nonnull)placementId catalogItemId:(NSStri
103134 });
104135}
105136
137+ // / Registers a callback to receive events from a specific Rokt placement.
138+ // / Use this to listen for events like placement shown, offer selected, placement closed, etc.
139+ // / - Parameters:
140+ // / - identifier: The Rokt placement identifier to listen for events from
141+ // / - onEvent: Callback block that receives MPRoktEvent objects when placement events occur
106142- (void )events : (NSString * _Nonnull)identifier onEvent : (void (^ _Nullable)(MPRoktEvent * _Nonnull))onEvent {
107143 dispatch_async (dispatch_get_main_queue (), ^{
108144 // Forwarding call to kits
@@ -120,6 +156,8 @@ - (void)events:(NSString * _Nonnull)identifier onEvent:(void (^ _Nullable)(MPRok
120156 });
121157}
122158
159+ // / Closes any currently displayed Rokt placement.
160+ // / Call this method to programmatically dismiss an active Rokt overlay or embedded placement.
123161- (void )close {
124162 dispatch_async (dispatch_get_main_queue (), ^{
125163 // Forwarding call to kits
@@ -132,17 +170,28 @@ - (void)close {
132170 });
133171}
134172
135- - (NSArray <NSDictionary<NSString *, NSString *> *> *)getRoktPlacementAttributesMapping {
136- NSArray <NSDictionary <NSString *, NSString *> *> *attributeMap = nil ;
137-
138- // Get the kit configuration
173+ #pragma mark - Private Helper Methods
174+
175+ // / Retrieves the Rokt Kit configuration from the kit container.
176+ // / @return The Rokt Kit configuration dictionary, or nil if Rokt Kit is not configured.
177+ - (NSDictionary * _Nullable)getRoktKitConfiguration {
139178 NSArray <NSDictionary *> *kitConfigs = [MParticle sharedInstance ].kitContainer_PRIVATE .originalConfig .copy ;
140- NSDictionary *roktKitConfig;
141179 for (NSDictionary *kitConfig in kitConfigs) {
142- if (kitConfig[ @" id " ] != nil && [ kitConfig[@" id " ] integerValue ] == 181 ) {
143- roktKitConfig = kitConfig;
180+ if ([ kitConfig[kMPKitConfigurationIdKey ] integerValue ] == kMPRoktKitId ) {
181+ return kitConfig;
144182 }
145183 }
184+ return nil ;
185+ }
186+
187+ // / Retrieves the attribute mapping configuration for the Rokt Kit from the mParticle dashboard settings.
188+ // / The mapping defines how attribute keys should be renamed before being sent to Rokt (e.g., "userEmail" → "email").
189+ // / @return An array of mapping dictionaries with "map" (source key) and "value" (destination key), or nil if Rokt Kit is not configured.
190+ - (NSArray <NSDictionary<NSString *, NSString *> *> *)getRoktPlacementAttributesMapping {
191+ NSArray <NSDictionary <NSString *, NSString *> *> *attributeMap = nil ;
192+
193+ // Get the kit configuration
194+ NSDictionary *roktKitConfig = [self getRoktKitConfiguration ];
146195
147196 // Return nil if no Rokt Kit configuration found
148197 if (!roktKitConfig) {
@@ -181,15 +230,12 @@ - (void)close {
181230 return attributeMap;
182231}
183232
233+ // / Retrieves the configured identity type to use for hashed email from the Rokt Kit configuration.
234+ // / The hashed email identity type is determined by dashboard settings and may vary (e.g., CustomerId, Other, etc.).
235+ // / @return The NSNumber representing the MPIdentity type for hashed email, or nil if not configured.
184236- (NSNumber *)getRoktHashedEmailUserIdentityType {
185237 // Get the kit configuration
186- NSArray <NSDictionary *> *kitConfigs = [MParticle sharedInstance ].kitContainer_PRIVATE .originalConfig .copy ;
187- NSDictionary *roktKitConfig;
188- for (NSDictionary *kitConfig in kitConfigs) {
189- if (kitConfig[@" id" ] != nil && [kitConfig[@" id" ] integerValue ] == 181 ) {
190- roktKitConfig = kitConfig;
191- }
192- }
238+ NSDictionary *roktKitConfig = [self getRoktKitConfiguration ];
193239
194240 // Get the string representing which identity to use and convert it to the key (NSNumber)
195241 NSString *hashedIdentityTypeString = roktKitConfig[kMPRemoteConfigKitConfigurationKey ][kMPHashedEmailUserIdentityType ];
@@ -198,25 +244,36 @@ - (NSNumber *)getRoktHashedEmailUserIdentityType {
198244 return hashedIdentityTypeNumber;
199245}
200246
247+ // / Ensures the "sandbox" attribute is present in the attributes dictionary.
248+ // / If not already set by the caller, the sandbox value is automatically determined based on the current mParticle environment
249+ // / (MPEnvironmentDevelopment → "true", production → "false"). This tells Rokt whether to show test or production ads.
250+ // / - Parameter attributes: The input attributes dictionary to validate
251+ // / @return A dictionary with the sandbox attribute guaranteed to be present
201252- (NSDictionary <NSString *, NSString *> *)confirmSandboxAttribute : (NSDictionary <NSString *, NSString *> * _Nullable)attributes {
202253 NSMutableDictionary <NSString *, NSString *> *finalAttributes = attributes.mutableCopy ;
203- NSString *sandboxKey = @" sandbox" ;
204254
205255 // Determine the value of the sandbox attribute based off the current environment
206256 NSString *sandboxValue = ([[MParticle sharedInstance ] environment ] == MPEnvironmentDevelopment) ? @" true" : @" false" ;
207257
208258 if (finalAttributes != nil ) {
209259 // Only set sandbox if it`s not set by the client
210- if (![finalAttributes.allKeys containsObject: sandboxKey ]) {
211- finalAttributes[sandboxKey ] = sandboxValue;
260+ if (![finalAttributes.allKeys containsObject: kMPRoktAttributeKeySandbox ]) {
261+ finalAttributes[kMPRoktAttributeKeySandbox ] = sandboxValue;
212262 }
213263 } else {
214- finalAttributes = [[NSMutableDictionary alloc ] initWithDictionary: @{sandboxKey : sandboxValue}];
264+ finalAttributes = [[NSMutableDictionary alloc ] initWithDictionary: @{kMPRoktAttributeKeySandbox : sandboxValue}];
215265 }
216266
217267 return finalAttributes;
218268}
219269
270+ // / Synchronizes user identity with mParticle if email or hashed email is provided in attributes.
271+ // / If the email or hashed email in attributes differs from the current user's identity, this method performs
272+ // / an identity API call to update the user before proceeding. This ensures Rokt has the most current user identity.
273+ // / - Parameters:
274+ // / - attributes: Dictionary that may contain "email" or "emailsha256" keys
275+ // / - user: The current mParticle user
276+ // / - completion: Completion handler called with the resolved (possibly updated) user
220277- (void )confirmUser : (NSDictionary <NSString *, NSString *> * _Nullable)attributes user : (MParticleUser * _Nullable)user completion : (void (^)(MParticleUser *_Nullable))completion {
221278 NSString *email = attributes[@" email" ];
222279 NSString *hashedEmail = attributes[@" emailsha256" ];
0 commit comments