Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 24 additions & 9 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ permissions:
checks: write
id-token: write

env:
XCODE_VERSION: "16.4"
DEVICE: "iPhone 16 Pro"
VERSION: ">=18.0"

jobs:
pr-branch-check-name:
name: "Check PR for semantic branch name"
Expand All @@ -23,20 +28,30 @@ jobs:

test:
name: Test
timeout-minutes: 15
runs-on: macos-15
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up Xcode 16
uses: actions/checkout@v6

- name: Set up Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: 16.3.0
- name: Run Tests
run: >
set -o pipefail &&
xcodebuild test -project mParticle-Rokt.xcodeproj -scheme mParticle_RoktTests -destination 'platform=iOS Simulator,name=iPhone 16,OS=latest'
| xcbeautify --renderer github-actions
shell: bash
xcode-version: ${{ env.XCODE_VERSION }}

- name: Setup specified simulator
uses: futureware-tech/simulator-action@v4
id: simulator
with:
model: ${{ env.DEVICE }}
os: iOS
os_version: ${{ env.VERSION }}
erase_before_boot: true
wait_for_boot: true
shutdown_after_job: true

- name: Run unit tests
run: xcodebuild -project mParticle-Rokt.xcodeproj -scheme mParticle_RoktTests -destination 'id=${{ steps.simulator.outputs.UDID }}' test

pr-notify:
if: >
Expand Down
3 changes: 3 additions & 0 deletions mParticle-Rokt-Swift/MPRoktLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ public class MPRoktLayout {
confirmUser(attributes: attributes) { identifyCalled in
let preparedAttributes = MPKitRokt.prepareAttributes(attributes, filteredUser: Optional<FilteredMParticleUser>.none, performMapping: true)

// Log custom event for selectPlacements call
MPKitRokt.logSelectPlacementEvent(preparedAttributes)

MPRoktLayout.mpLog("Initializing RoktLayout with arguments sdkTriggered:\(sdkTriggered.wrappedValue), viewName: \(viewName ?? "nil"), locationName:\(locationName), attributes:\(preparedAttributes)")
self.roktLayout = RoktLayout.init(
sdkTriggered: sdkTriggered,
Expand Down
1 change: 1 addition & 0 deletions mParticle-Rokt/MPKitRokt.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@

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

@end
11 changes: 11 additions & 0 deletions mParticle-Rokt/MPKitRokt.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
NSString * const kMPPlacementAttributesMapping = @"placementAttributesMapping";
NSString * const kMPHashedEmailUserIdentityType = @"hashedEmailUserIdentityType";
NSString * const kMPRoktEmbeddedViewClassName = @"MPRoktEmbeddedView";
NSString * const kMPEventNameSelectPlacements = @"selectPlacements";
NSInteger const kMPRoktKitCode = 181;

static __weak MPKitRokt *roktKit = nil;
Expand Down Expand Up @@ -104,6 +105,9 @@ - (MPKitExecStatus *)executeWithIdentifier:(NSString * _Nullable)identifier
[MPKitRokt MPLog:[NSString stringWithFormat:@"Rokt Kit recieved `executeWithIdentifier` method with the following arguments: \n identifier: %@ \n attributes: %@ \n embeddedViews: %@ \n config: %@ \n callbacks: %@ \n filteredUser identities: %@", identifier, attributes, embeddedViews, mpRoktConfig, callbacks, filteredUser.userIdentities]];
NSDictionary<NSString *, NSString *> *finalAtt = [MPKitRokt prepareAttributes:attributes filteredUser:filteredUser performMapping:NO];

// Log custom event for selectPlacements call
[MPKitRokt logSelectPlacementEvent:finalAtt];

//Convert MPRoktConfig to RoktConfig
RoktConfig *roktConfig = [MPKitRokt convertMPRoktConfig:mpRoktConfig];
NSDictionary<NSString *, RoktEmbeddedView *> *confirmedViews = [self confirmEmbeddedViews:embeddedViews];
Expand Down Expand Up @@ -786,6 +790,13 @@ + (void)MPLog:(NSString *)string {
}
}

+ (void)logSelectPlacementEvent:(NSDictionary<NSString *, NSString *> * _Nonnull)attributes {
MPEvent *event = [[MPEvent alloc] initWithName:kMPEventNameSelectPlacements type:MPEventTypeOther];
event.customAttributes = attributes;
[[MParticle sharedInstance] logEvent:event];
[MPKitRokt MPLog:[NSString stringWithFormat:@"Logged selectplacements custom event with attributes: %@", attributes]];
}


+ (MPRoktEvent * _Nullable)mapEvent:(RoktEvent *)event {
if (!event) {
Expand Down
33 changes: 33 additions & 0 deletions mParticle_RoktTests/mParticle_Rokt_SwiftTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,39 @@ struct mParticle_Rokt_SwiftTests {
#expect(layout.roktLayout != nil, "Layout should handle state changes")
}

// MARK: - SelectPlacements Custom Event Tests

@available(iOS 15, *)
@Test func testPrepareAttributesLogsAttributesEvent() {
// Given
let attributes: [String: String] = ["attr1": "val1"]

// When
let preparedAttributes = MPKitRokt.prepareAttributes(
attributes,
filteredUser: nil,
performMapping: false
)

MPKitRokt.logSelectPlacementEvent(preparedAttributes)

// Then
#expect(preparedAttributes["sandbox"] != nil, "Sandbox attribute should be present")
#expect(preparedAttributes.count >= 1, "Prepared attributes should contain at least the sandbox attribute")
}

@available(iOS 15, *)
@Test func testLogSelectPlacementEventHandlesNilMParticleInstance() {
// Given
let attributes: [String: String] = ["key1": "value1"]

// When
MPKitRokt.logSelectPlacementEvent(attributes)

// Then
#expect(true, "logSelectPlacementEvent should handle MParticle instance state gracefully")
}

// MARK: - Integration Tests

@MainActor @available(iOS 15, *)
Expand Down
Loading