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
22 changes: 18 additions & 4 deletions .github/workflows/native-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ env:
jobs:
native-unit-tests:
strategy:
fail-fast: false
max-parallel: 4
matrix:
platform: [iOS, tvOS]
Expand All @@ -26,10 +27,23 @@ jobs:
runs-on: macOS-15
steps:
- name: Checkout
uses: actions/checkout@v5
uses: actions/checkout@v6

- name: Select Xcode
run: sudo xcode-select -s /Applications/Xcode_${{ env.XCODE_VERSION }}.app
- name: Set up Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: ${{ env.XCODE_VERSION }}

- name: Setup specified simulator
uses: futureware-tech/simulator-action@v4
id: simulator
with:
model: ${{ matrix.device }}
os: ${{ matrix.platform }}
os_version: '>=18.0'
erase_before_boot: true
wait_for_boot: true
shutdown_after_job: true

- name: Run unit tests
run: xcodebuild -project mParticle-Apple-SDK.xcodeproj -scheme ${{ matrix.scheme }} -destination 'platform=${{ matrix.platform }} Simulator,name=${{ matrix.device }},OS=latest' test
run: xcodebuild -project mParticle-Apple-SDK.xcodeproj -scheme ${{ matrix.scheme }} -destination 'id=${{ steps.simulator.outputs.UDID }}' test
67 changes: 56 additions & 11 deletions UnitTests/ObjCTests/MPRoktTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -293,17 +293,19 @@ - (void)testGetRoktPlacementAttributesMapping {
self.mockInstance = OCMPartialMock(instance);
self.mockContainer = OCMClassMock([MPKitContainer_PRIVATE class]);
NSArray *kitConfig = @[@{
@"AllowJavaScriptResponse": @"True",
@"accountId": @12345,
@"onboardingExpProvider": @"None",
kMPPlacementAttributesMapping: @"[{\"jsmap\":null,\"map\":\"f.name\",\"maptype\":\"UserAttributeClass.Name\",\"value\":\"firstname\"},{\"jsmap\":null,\"map\":\"zip\",\"maptype\":\"UserAttributeClass.Name\",\"value\":\"billingzipcode\"},{\"jsmap\":null,\"map\":\"l.name\",\"maptype\":\"UserAttributeClass.Name\",\"value\":\"lastname\"}]",
@"sandboxMode": @"True",
@"eau": @0,
@"hs": @{
@"pur": @{},
@"reg": @{}
},
@"id": @181
@"id": @181,
kMPRemoteConfigKitConfigurationKey: @{
@"AllowJavaScriptResponse": @"True",
@"accountId": @12345,
@"onboardingExpProvider": @"None",
kMPPlacementAttributesMapping: @"[{\"jsmap\":null,\"map\":\"f.name\",\"maptype\":\"UserAttributeClass.Name\",\"value\":\"firstname\"},{\"jsmap\":null,\"map\":\"zip\",\"maptype\":\"UserAttributeClass.Name\",\"value\":\"billingzipcode\"},{\"jsmap\":null,\"map\":\"l.name\",\"maptype\":\"UserAttributeClass.Name\",\"value\":\"lastname\"}]",
@"sandboxMode": @"True",
@"eau": @0,
@"hs": @{
@"pur": @{},
@"reg": @{}
}
}
}];
[[[self.mockContainer stub] andReturn:kitConfig] originalConfig];
[[[self.mockInstance stub] andReturn:self.mockContainer] kitContainer_PRIVATE];
Expand All @@ -315,6 +317,49 @@ - (void)testGetRoktPlacementAttributesMapping {
XCTAssertEqualObjects(testResult, expectedResult, @"Mapping does not match .");
}

- (void)testGetRoktHashedEmailUserIdentityType {
MParticle *instance = [MParticle sharedInstance];
self.mockInstance = OCMPartialMock(instance);
self.mockContainer = OCMClassMock([MPKitContainer_PRIVATE class]);
NSArray *kitConfig = @[@{
@"id": @181,
kMPRemoteConfigKitConfigurationKey: @{
@"AllowJavaScriptResponse": @"True",
@"accountId": @12345,
kMPHashedEmailUserIdentityType: @"other3",
@"sandboxMode": @"True"
}
}];
[[[self.mockContainer stub] andReturn:kitConfig] originalConfig];
[[[self.mockInstance stub] andReturn:self.mockContainer] kitContainer_PRIVATE];
[[[self.mockInstance stub] andReturn:self.mockInstance] sharedInstance];

NSNumber *testResult = [self.rokt getRoktHashedEmailUserIdentityType];

XCTAssertEqualObjects(testResult, @(MPIdentityOther3), @"Hashed email identity type does not match.");
}

- (void)testGetRoktHashedEmailUserIdentityTypeReturnsNilWhenNotConfigured {
MParticle *instance = [MParticle sharedInstance];
self.mockInstance = OCMPartialMock(instance);
self.mockContainer = OCMClassMock([MPKitContainer_PRIVATE class]);
NSArray *kitConfig = @[@{
@"id": @181,
kMPRemoteConfigKitConfigurationKey: @{
@"AllowJavaScriptResponse": @"True",
@"accountId": @12345,
@"sandboxMode": @"True"
}
}];
[[[self.mockContainer stub] andReturn:kitConfig] originalConfig];
[[[self.mockInstance stub] andReturn:self.mockContainer] kitContainer_PRIVATE];
[[[self.mockInstance stub] andReturn:self.mockInstance] sharedInstance];

NSNumber *testResult = [self.rokt getRoktHashedEmailUserIdentityType];

XCTAssertNil(testResult, @"Hashed email identity type should be nil when not configured.");
}

- (void)testSelectPlacementsIdentifyUser {
[[[self.mockRokt stub] andReturn:@[]] getRoktPlacementAttributesMapping];
MParticle *instance = [MParticle sharedInstance];
Expand Down
14 changes: 14 additions & 0 deletions mParticle-Apple-SDK/Identity/FilteredMParticleUser.m
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
#import "FilteredMParticleUser.h"
#import "mParticle.h"
#import "MParticleUser.h"
#import "MPStateMachine.h"
#import "MPKitConfiguration.h"
#import "MPDataPlanFilter.h"
#import "MParticleSwift.h"

@interface MParticle ()

@property (nonatomic, strong) id<MPDataPlanFilterProtocol> dataPlanFilter;
@property (nonatomic, strong, readonly) MPStateMachine_PRIVATE *stateMachine;

@end

Expand Down Expand Up @@ -39,6 +41,18 @@ -(BOOL)isLoggedIn {
return self.user.isLoggedIn;
}

-(NSString *)idfa {
NSNumber *currentStatus = [MParticle sharedInstance].stateMachine.attAuthorizationStatus;
if (currentStatus != nil && currentStatus.integerValue == MPATTAuthorizationStatusAuthorized) {
return self.user.identities[@(MPIdentityIOSAdvertiserId)];
}
return nil;
}

-(NSString *)idfv {
return self.user.identities[@(MPIdentityIOSVendorId)];
}

-(NSDictionary<NSNumber *, NSString *> *) userIdentities {
NSDictionary<NSNumber *, NSString *> *unfilteredUserIdentities = self.user.identities;
NSMutableDictionary *userIdentities = [NSMutableDictionary dictionary];
Expand Down
14 changes: 14 additions & 0 deletions mParticle-Apple-SDK/Include/FilteredMParticleUser.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,20 @@
*/
@property (readonly, strong, nonnull) NSDictionary<NSNumber *, NSString *> *userIdentities;

/**
Gets current user's IDFA (readonly)
@returns A string that represents a unique, resettable device identifier that allows developers to track user activity for personalized ads. This will always be nil if ATTStatus is not set to authorized.
@see MPIdentityIOSAdvertiserId
*/
@property (readonly, strong, nullable) NSString *idfa;

/**
Gets current user's IDFV (readonly)
@returns A string that represents a unique, non-resettable alphanumeric code Apple assigns to a specific device, identical for all apps from the same developer on that device.
@see MPIdentityIOSVendorId
*/
@property (readonly, strong, nullable) NSString *idfv;

/**
Gets all user attributes.
@returns A dictionary containing the collection of user attributes.
Expand Down
1 change: 1 addition & 0 deletions mParticle-Apple-SDK/MPIConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ extern NSString * _Nonnull const kMPRemoteConfigAppDefined;
extern NSString * _Nonnull const kMPRemoteConfigForceTrue;
extern NSString * _Nonnull const kMPRemoteConfigForceFalse;
extern NSString * _Nonnull const kMPRemoteConfigKitsKey;
extern NSString * _Nonnull const kMPRemoteConfigKitConfigurationKey;
extern NSString * _Nonnull const kMPRemoteConfigKitHashesKey;
extern NSString * _Nonnull const kMPRemoteConfigConsumerInfoKey;
extern NSString * _Nonnull const kMPRemoteConfigCookiesKey;
Expand Down
1 change: 1 addition & 0 deletions mParticle-Apple-SDK/MPIConstants.m
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@
NSString *const kMPRemoteConfigForceTrue = @"forcetrue";
NSString *const kMPRemoteConfigForceFalse = @"forcefalse";
NSString *const kMPRemoteConfigKitsKey = @"eks";
NSString *const kMPRemoteConfigKitConfigurationKey = @"as";
NSString *const kMPRemoteConfigKitHashesKey = @"hs";
NSString *const kMPRemoteConfigConsumerInfoKey = @"ci";
NSString *const kMPRemoteConfigCookiesKey = @"ck";
Expand Down
Loading
Loading