Skip to content
Merged
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
11 changes: 10 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ let package = Package(
products: [
.library(
name: "mParticle-Rokt",
targets: ["mParticle-Rokt"]),
targets: ["mParticle-Rokt-Swift"]),
],
dependencies: [
.package(name: "mParticle-Apple-SDK",
Expand All @@ -29,5 +29,14 @@ let package = Package(
path: "mParticle-Rokt",
publicHeadersPath: "."
),
.target(
name: "mParticle-Rokt-Swift",
dependencies: [
"mParticle-Rokt",
.product(name: "mParticle-Apple-SDK", package: "mParticle-Apple-SDK"),
.product(name: "Rokt-Widget", package: "Rokt-Widget"),
],
path: "mParticle-Rokt-Swift"
),
]
)
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import SwiftUI
import Rokt_Widget
import mParticle_Apple_SDK
import mParticle_Rokt

@available(iOS 15, *)
public struct MPRoktLayout: View {
Expand Down
23 changes: 19 additions & 4 deletions mParticle-Rokt.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,23 @@ Pod::Spec.new do |s|
s.swift_version = '5.3'

s.ios.deployment_target = "12.0"
s.ios.source_files = 'mParticle-Rokt/*.{h,m,swift}'
s.ios.public_header_files = 'mParticle-Rokt/*.h'
s.ios.dependency 'mParticle-Apple-SDK', '~> 8.0'
s.ios.dependency 'Rokt-Widget', '~> 4.10'

# Objective-C subspec
s.subspec 'ObjC' do |objc|
objc.source_files = 'mParticle-Rokt/*.{h,m}'
objc.public_header_files = 'mParticle-Rokt/*.h'
objc.dependency 'mParticle-Apple-SDK', '~> 8.0'
objc.dependency 'Rokt-Widget', '~> 4.10'
end

# Swift subspec
s.subspec 'Swift' do |swift|
swift.source_files = 'mParticle-Rokt-Swift/*.swift'
swift.dependency 'mParticle-Rokt/ObjC'
swift.dependency 'mParticle-Apple-SDK', '~> 8.0'
swift.dependency 'Rokt-Widget', '~> 4.10'
end

# Default includes both
s.default_subspecs = 'ObjC', 'Swift'
end
265 changes: 256 additions & 9 deletions mParticle-Rokt.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
Comment thread
thomson-t marked this conversation as resolved.
<Scheme
LastUpgradeVersion = "1640"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7E9623582E3BB272005905F4"
BuildableName = "mParticle_Rokt_Swift.framework"
BlueprintName = "mParticle-Rokt-Swift"
ReferencedContainer = "container:mParticle-Rokt.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "7E9623582E3BB272005905F4"
BuildableName = "mParticle_Rokt_Swift.framework"
BlueprintName = "mParticle-Rokt-Swift"
ReferencedContainer = "container:mParticle-Rokt.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
103 changes: 101 additions & 2 deletions mParticle-Rokt/MPKitRokt.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#import "MPKitRokt.h"
#import <Rokt_Widget/Rokt_Widget-Swift.h>
#import <mParticle_Rokt/mParticle_Rokt-Swift.h>

NSString * const kMPRemoteConfigKitHashesKey = @"hs";
NSString * const kMPRemoteConfigUserAttributeFilter = @"ua";
Expand Down Expand Up @@ -457,7 +456,7 @@ - (MPKitExecStatus *)purchaseFinalized:(NSString *)placementId catalogItemId:(NS

- (MPKitExecStatus *)events:(NSString *)identifier onEvent:(void (^)(MPRoktEvent * _Nonnull))onEvent {
[Rokt eventsWithViewName:identifier onEvent:^(RoktEvent * _Nonnull event) {
MPRoktEvent *mpEvent = [MPRoktEventMapper mapEvent:event];
MPRoktEvent *mpEvent = [MPKitRokt mapEvent:event];
if (mpEvent) {
onEvent(mpEvent);
}
Expand Down Expand Up @@ -742,4 +741,104 @@ - (MPKitExecStatus *)setOptOut:(BOOL)optOut {
return [self execStatus:MPKitReturnCodeSuccess];
}

+ (MPRoktEvent * _Nullable)mapEvent:(RoktEvent *)event {
if (!event) {
return nil;
}

// Check for RoktEvent.InitComplete
if ([event isKindOfClass:[InitComplete class]]) {
InitComplete *initComplete = (InitComplete *)event;
return [[MPRoktInitComplete alloc] initWithSuccess:initComplete.success];
}

// Check for RoktEvent.ShowLoadingIndicator
if ([event isKindOfClass:[ShowLoadingIndicator class]]) {
return [[MPRoktShowLoadingIndicator alloc] init];
}

// Check for RoktEvent.HideLoadingIndicator
if ([event isKindOfClass:[HideLoadingIndicator class]]) {
return [[MPRoktHideLoadingIndicator alloc] init];

}

// Check for RoktEvent.PlacementInteractive
if ([event isKindOfClass:[PlacementInteractive class]]) {
PlacementInteractive *placementInteractive = (PlacementInteractive *)event;
return [[MPRoktPlacementInteractive alloc] initWithPlacementId:placementInteractive.placementId];
}

// Check for RoktEvent.PlacementReady
if ([event isKindOfClass:[PlacementReady class]]) {
PlacementReady *placementReady = (PlacementReady *)event;
return [[MPRoktPlacementReady alloc] initWithPlacementId:placementReady.placementId];
}

// Check for RoktEvent.OfferEngagement
if ([event isKindOfClass:[OfferEngagement class]]) {
OfferEngagement *offerEngagement = (OfferEngagement *)event;
return [[MPRoktOfferEngagement alloc] initWithPlacementId:offerEngagement.placementId];
}

// Check for RoktEvent.OpenUrl
if ([event isKindOfClass:[OpenUrl class]]) {
OpenUrl *openUrl = (OpenUrl *)event;
return [[MPRoktOpenUrl alloc] initWithPlacementId:openUrl.placementId url:openUrl.url];
}

// Check for RoktEvent.PositiveEngagement
if ([event isKindOfClass:[PositiveEngagement class]]) {
PositiveEngagement *positiveEngagement = (PositiveEngagement *)event;
return [[MPRoktPositiveEngagement alloc] initWithPlacementId:positiveEngagement.placementId];
}

// Check for RoktEvent.PlacementClosed
if ([event isKindOfClass:[PlacementClosed class]]) {
PlacementClosed *placementClosed = (PlacementClosed *)event;
return [[MPRoktPlacementClosed alloc] initWithPlacementId:placementClosed.placementId];
}

// Check for RoktEvent.PlacementCompleted
if ([event isKindOfClass:[PlacementCompleted class]]) {
PlacementCompleted *placementCompleted = (PlacementCompleted *)event;
return [[MPRoktPlacementCompleted alloc] initWithPlacementId:placementCompleted.placementId];
}

// Check for RoktEvent.PlacementFailure
if ([event isKindOfClass:[PlacementFailure class]]) {
PlacementFailure *placementFailure = (PlacementFailure *)event;
return [[MPRoktPlacementFailure alloc] initWithPlacementId:placementFailure.placementId];
}

// Check for RoktEvent.FirstPositiveEngagement
if ([event isKindOfClass:[FirstPositiveEngagement class]]) {
FirstPositiveEngagement *firstPositiveEngagement = (FirstPositiveEngagement *)event;
return [[MPRoktFirstPositiveEngagement alloc] initWithPlacementId:firstPositiveEngagement.placementId];
}

// Check for RoktEvent.CartItemInstantPurchase
if ([event isKindOfClass:[CartItemInstantPurchase class]]) {
CartItemInstantPurchase *cartItemInstantPurchase = (CartItemInstantPurchase *)event;

// Handle nil coalescing for name field
NSString *name = cartItemInstantPurchase.name ?: @"";

return [[MPRoktCartItemInstantPurchase alloc] initWithPlacementId:cartItemInstantPurchase.placementId
name:name
cartItemId:cartItemInstantPurchase.cartItemId
catalogItemId:cartItemInstantPurchase.catalogItemId
currency:cartItemInstantPurchase.currency
description:cartItemInstantPurchase.description
linkedProductId:cartItemInstantPurchase.linkedProductId
providerData:cartItemInstantPurchase.providerData
quantity:cartItemInstantPurchase.quantity
totalPrice:cartItemInstantPurchase.totalPrice
unitPrice:cartItemInstantPurchase.unitPrice];
}

// Default case - return nil if no matching event type found
return nil;
}

@end
73 changes: 0 additions & 73 deletions mParticle-Rokt/MPRoktEventMapper.swift

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@
#import <Rokt_Widget/Rokt_Widget-Swift.h>
#import <mParticle_Rokt/mParticle_Rokt.h>
#import "MPKitRokt.h"
#import <mParticle_Rokt/mParticle_Rokt-Swift.h>
1 change: 0 additions & 1 deletion mParticle_RoktTests/mParticle_RoktTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#import <Rokt_Widget/Rokt_Widget-Swift.h>
#import <mParticle_Rokt/mParticle_Rokt.h>
#import "MPKitRokt.h"
#import <mParticle_Rokt/mParticle_Rokt-Swift.h>

@interface MPKitRokt ()

Expand Down
1 change: 1 addition & 0 deletions mParticle_RoktTests/mParticle_Rokt_SwiftTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import SwiftUI
@testable import mParticle_Rokt
import Rokt_Widget
import mParticle_Rokt_Swift

struct mParticle_Rokt_SwiftTests {

Expand All @@ -30,7 +31,7 @@
)

// Then
#expect(layout.body != nil, "Layout body should not be nil")

Check warning on line 34 in mParticle_RoktTests/mParticle_Rokt_SwiftTests.swift

View workflow job for this annotation

GitHub Actions / Test

comparing non-optional value of type 'some View' to 'nil' always returns true
}

@MainActor @available(iOS 15, *)
Expand All @@ -57,7 +58,7 @@
)

// Then
#expect(layout.body != nil, "Layout body should not be nil")

Check warning on line 61 in mParticle_RoktTests/mParticle_Rokt_SwiftTests.swift

View workflow job for this annotation

GitHub Actions / Test

comparing non-optional value of type 'some View' to 'nil' always returns true
}

@MainActor @available(iOS 15, *)
Expand All @@ -75,7 +76,7 @@
)

// Then
#expect(layout.body != nil, "Layout should handle empty attributes")

Check warning on line 79 in mParticle_RoktTests/mParticle_Rokt_SwiftTests.swift

View workflow job for this annotation

GitHub Actions / Test

comparing non-optional value of type 'some View' to 'nil' always returns true
}

@MainActor @available(iOS 15, *)
Expand All @@ -93,7 +94,7 @@
)

// Then
#expect(layout.body != nil, "Layout should handle sandbox attribute")

Check warning on line 97 in mParticle_RoktTests/mParticle_Rokt_SwiftTests.swift

View workflow job for this annotation

GitHub Actions / Test

comparing non-optional value of type 'some View' to 'nil' always returns true
}

// MARK: - Attribute Preparation Tests
Expand All @@ -111,7 +112,7 @@
)

// Then
#expect(preparedAttributes != nil, "Prepared attributes should not be nil")

Check warning on line 115 in mParticle_RoktTests/mParticle_Rokt_SwiftTests.swift

View workflow job for this annotation

GitHub Actions / Test

comparing non-optional value of type '[String : String]' to 'nil' always returns true
#expect(preparedAttributes.count >= attributes.count, "Prepared attributes should contain at least the original attributes")
}

Expand All @@ -128,7 +129,7 @@
)

// Then
#expect(preparedAttributes != nil, "Prepared attributes should not be nil")

Check warning on line 132 in mParticle_RoktTests/mParticle_Rokt_SwiftTests.swift

View workflow job for this annotation

GitHub Actions / Test

comparing non-optional value of type '[String : String]' to 'nil' always returns true
#expect(preparedAttributes["sandbox"] != nil, "Sandbox attribute should be added automatically")
}

Expand Down Expand Up @@ -182,7 +183,7 @@
)

// Then
#expect(layout is any View, "MPRoktLayout should conform to SwiftUI View protocol")

Check warning on line 186 in mParticle_RoktTests/mParticle_Rokt_SwiftTests.swift

View workflow job for this annotation

GitHub Actions / Test

'is' test is always true
}

@MainActor @available(iOS 15, *)
Expand All @@ -200,7 +201,7 @@

// Then
let body = layout.body
#expect(body != nil, "Layout body should be accessible")

Check warning on line 204 in mParticle_RoktTests/mParticle_Rokt_SwiftTests.swift

View workflow job for this annotation

GitHub Actions / Test

comparing non-optional value of type 'some View' to 'nil' always returns true
}

// MARK: - Parameter Validation Tests
Expand All @@ -220,7 +221,7 @@
)

// Then
#expect(layout.body != nil, "Layout should handle long location names")

Check warning on line 224 in mParticle_RoktTests/mParticle_Rokt_SwiftTests.swift

View workflow job for this annotation

GitHub Actions / Test

comparing non-optional value of type 'some View' to 'nil' always returns true
}

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