Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
906bbed
Add delay to config
nonelse Mar 10, 2025
617316d
Save first session manager approach
nonelse Mar 12, 2025
7a3d1e5
Queue apis that reach ActHandl
nonelse Mar 12, 2025
0b001d3
Replace timer with boolean
nonelse Mar 14, 2025
67ba126
Add stop delay api
nonelse Mar 14, 2025
c00fc58
Fix config option copy
nonelse Mar 18, 2025
bac6ab6
Inject foreground
nonelse Mar 18, 2025
d46a6fb
Add command for delay
nonelse Mar 18, 2025
f7aa204
Flag for waiting for main thread
nonelse Mar 18, 2025
b8c5176
Refac process cached pre launch actions
nonelse Mar 19, 2025
88d740a
Queued remaining api actions
nonelse Mar 19, 2025
59e05ef
Add coppa api in delay
nonelse Mar 21, 2025
8c5e90d
set external device id in delay
nonelse Mar 21, 2025
92ec46b
Add external device id delay
nonelse Mar 24, 2025
915b61c
Add commands for delay
nonelse Mar 24, 2025
6e7b66b
Add check for coppa in delayed actions
nonelse Mar 24, 2025
112820d
Remove unused constant
nonelse Mar 28, 2025
ef4c85b
refac: merge apiActionWithBlock: and preLaunchActionWithBlock:
uerceg Mar 27, 2025
9d13fb4
Fix rebase miss
nonelse Mar 28, 2025
8da4760
Rename stop to end
nonelse Mar 28, 2025
dcc5c14
chore: add public header comments
uerceg Mar 28, 2025
7bdcc7b
feat: add first session delay to web bridge
uerceg Mar 28, 2025
4434348
feat: improve first session logging a bit
uerceg Apr 3, 2025
dd39bbe
Add ff first session delay
nonelse Apr 8, 2025
a2d7241
Sync new entry points
nonelse Apr 9, 2025
abd44d0
Replace string state with enum
nonelse Apr 9, 2025
341ee5c
Extract init sdk block
nonelse Apr 9, 2025
6d379e3
remove line break
nonelse Apr 9, 2025
89b8b15
remove header
nonelse Apr 9, 2025
74cbb6f
remove comment
nonelse Apr 9, 2025
07ff6e8
rearranged methods
nonelse Apr 9, 2025
a81494a
prevent att delay with first session delay
nonelse Apr 9, 2025
c30b1f5
Fix feature flag
nonelse Apr 9, 2025
a07386a
Replace volatile flage with atomic bool
nonelse Apr 10, 2025
ffa6840
Add syncronization for system lifecycle
nonelse Apr 10, 2025
04a6a14
refac: naming changes, nullability annotations, and typo fix in appli…
genadyb Apr 11, 2025
dec85d7
Remove volatile and revert naming
nonelse Apr 11, 2025
8fbae90
test: run tests
uerceg Apr 15, 2025
00b9adb
feat: update version number to 5.3.0
uerceg Apr 15, 2025
abcbb5b
docs: update changelog
uerceg Apr 15, 2025
876e5f3
docs: update changelog
uerceg Apr 15, 2025
a1713c7
docs: update changelog
uerceg Apr 16, 2025
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
2 changes: 1 addition & 1 deletion Adjust.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "Adjust"
s.module_name = "AdjustSdk"
s.version = "5.2.0"
s.version = "5.3.0"
s.summary = "This is the iOS SDK of Adjust. You can read more about it at https://adjust.com."
s.homepage = "https://github.com/adjust/ios_sdk"
s.license = { :type => 'MIT', :file => 'LICENSE' }
Expand Down
12 changes: 10 additions & 2 deletions Adjust/ADJConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,17 @@ typedef NS_ENUM(NSUInteger, ADJLogLevel);
/**
* @brief Indicator of whether SDK should start in COPPA compliant mode or not.
*/
@property (nonatomic, readonly) BOOL isCoppaComplianceEnabled;
@property (nonatomic) BOOL isCoppaComplianceEnabled;

/**
* @brief Indicator of whether SDK should use AppTrackingTransparency framework
* @brief Indicator of whether SDK should use AppTrackingTransparency framework or not.
*/
@property (nonatomic, readonly) BOOL isAppTrackingTransparencyUsageEnabled;

/**
* @brief Indicator of whether SDK is in first session delay mode or not.
*/
@property (nonatomic, readonly) BOOL isFirstSessionDelayEnabled;

#pragma mark - AdjustConfig assignable properties

Expand Down Expand Up @@ -344,6 +348,10 @@ typedef NS_ENUM(NSUInteger, ADJLogLevel);
*/
- (void)enableCoppaCompliance;

/**
* @brief A method to enable SDK delay during the first session.
*/
- (void)enableFirstSessionDelay;
/**
* @brief A method to configure SDK avoid any call to AppTrackingTransparency framework.
*/
Expand Down
5 changes: 5 additions & 0 deletions Adjust/ADJConfig.m
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ - (void)disableAppTrackingTransparencyUsage {
_isAppTrackingTransparencyUsageEnabled = NO;
}

- (void)enableFirstSessionDelay {
_isFirstSessionDelayEnabled = YES;
}

- (void)setUrlStrategy:(nullable NSArray *)urlStrategyDomains
useSubdomains:(BOOL)useSubdomains
isDataResidency:(BOOL)isDataResidency {
Expand Down Expand Up @@ -241,6 +245,7 @@ - (id)copyWithZone:(NSZone *)zone {
copy->_isDeviceIdsReadingOnceEnabled = self.isDeviceIdsReadingOnceEnabled;
copy.eventDeduplicationIdsMaxSize = self.eventDeduplicationIdsMaxSize;
copy->_isAppTrackingTransparencyUsageEnabled = self.isAppTrackingTransparencyUsageEnabled;
copy->_isFirstSessionDelayEnabled = self.isFirstSessionDelayEnabled;
// AdjustDelegate not copied
}

Expand Down
24 changes: 23 additions & 1 deletion Adjust/Adjust.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Adjust.h
// Adjust SDK
//
// V5.2.0
// V5.3.0
// Created by Christian Wellenbrock (@wellle) on 23rd July 2013.
// Copyright (c) 2012-Present Adjust GmbH. All rights reserved.
//
Expand Down Expand Up @@ -285,6 +285,23 @@ extern NSString * __nonnull const ADJEnvironmentProduction;
*/
+ (void)lastDeeplinkWithCompletionHandler:(nonnull ADJLastDeeplinkGetterBlock)completion;

/**
* @brief Enable COPPA (Children's Online Privacy Protection Act) compliant for the application when is in first session delay
*/
+ (void)enableCoppaComplianceInDelay;

/**
* @brief Disable COPPA (Children's Online Privacy Protection Act) compliant for the application when is in first session delay
*/
+ (void)disableCoppaComplianceInDelay;

/**
* @brief Custom defined unique device ID (optional) when is in first session delay.
*
* @note Make sure to have a UNIQUE external ID for each user / device.
*/
+ (void)setExternalDeviceIdInDelay:(nullable NSString *)externalDeviceId;

/**
* @brief Verify in-app-purchase.
*
Expand All @@ -303,6 +320,11 @@ extern NSString * __nonnull const ADJEnvironmentProduction;
+ (void)verifyAndTrackAppStorePurchase:(nonnull ADJEvent *)event
withCompletionHandler:(nonnull ADJVerificationResultBlock)completion;

/**
* @brief End the first session delay that can be configured on ADJConfig instance.
*/
+ (void)endFirstSessionDelay;

/**
* Obtain singleton Adjust object.
*/
Expand Down
78 changes: 71 additions & 7 deletions Adjust/Adjust.m
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,24 @@ + (void)verifyAppStorePurchase:(nonnull ADJAppStorePurchase *)purchase
}
}

+ (void)enableCoppaComplianceInDelay {
@synchronized (self) {
[[Adjust getInstance] enableCoppaComplianceInDelay];
}
}

+ (void)disableCoppaComplianceInDelay {
@synchronized (self) {
[[Adjust getInstance] disableCoppaComplianceInDelay];
}
}

+ (void)setExternalDeviceIdInDelay:(nullable NSString *)externalDeviceId {
@synchronized (self) {
[[Adjust getInstance] setExternalDeviceIdInDelay:externalDeviceId];
}
}

+ (void)verifyAndTrackAppStorePurchase:(nonnull ADJEvent *)event
withCompletionHandler:(void (^_Nonnull)(ADJPurchaseVerificationResult * _Nonnull verificationResult))completion {
@synchronized (self) {
Expand All @@ -296,6 +314,13 @@ + (void)verifyAndTrackAppStorePurchase:(nonnull ADJEvent *)event
}
}

+ (void)endFirstSessionDelay {
@synchronized (self) {
[[Adjust getInstance] endFirstSessionDelay];
}
}


+ (void)setTestOptions:(NSDictionary *)testOptions {
@synchronized (self) {
if ([testOptions[@"teardown"] boolValue]) {
Expand Down Expand Up @@ -534,7 +559,6 @@ - (void)removeGlobalPartnerParameterForKey:(nonnull NSString *)key {
}

- (void)removeGlobalCallbackParameters {

if ([self checkActivityHandler:@"removing all global callback parameters"]) {
[self.activityHandler removeGlobalCallbackParameters];
return;
Expand Down Expand Up @@ -570,19 +594,26 @@ - (void)gdprForgetMe {

- (void)trackThirdPartySharing:(nonnull ADJThirdPartySharing *)thirdPartySharing {
if (![self checkActivityHandler:@"track third party sharing"]) {
if (self.savedPreLaunch.preLaunchAdjustThirdPartySharingArray == nil) {
self.savedPreLaunch.preLaunchAdjustThirdPartySharingArray =
[[NSMutableArray alloc] init];
if (self.savedPreLaunch.preLaunchActionsArray == nil) {
self.savedPreLaunch.preLaunchActionsArray = [[NSMutableArray alloc] init];
}
[self.savedPreLaunch.preLaunchAdjustThirdPartySharingArray addObject:thirdPartySharing];
[self.savedPreLaunch.preLaunchActionsArray addObject:^(ADJActivityHandler *activityHandler) {
[activityHandler tryTrackThirdPartySharingI:thirdPartySharing];
}];
return;
}
[self.activityHandler trackThirdPartySharing:thirdPartySharing];
}

- (void)trackMeasurementConsent:(BOOL)enabled {
if (![self checkActivityHandler:@"track measurement consent"]) {
self.savedPreLaunch.lastMeasurementConsentTracked = [NSNumber numberWithBool:enabled];
if (self.savedPreLaunch.preLaunchActionsArray == nil) {
self.savedPreLaunch.preLaunchActionsArray =
[[NSMutableArray alloc] init];
}
[self.savedPreLaunch.preLaunchActionsArray addObject:^(ADJActivityHandler *activityHandler) {
[activityHandler tryTrackMeasurementConsentI:enabled];
}];
return;
}
[self.activityHandler trackMeasurementConsent:enabled];
Expand Down Expand Up @@ -619,7 +650,8 @@ - (void)updateSkanConversionValue:(NSInteger)conversionValue
coarseValue:coarseValue
lockWindow:lockWindow
source:ADJSkanSourceClient
withCompletionHandler:^(NSDictionary * _Nonnull result) {
withCompletionHandler:^(NSDictionary * _Nonnull result)
{
if ([self checkActivityHandler]) {
[self.activityHandler invokeClientSkanUpdateCallbackWithResult:result];
}
Expand Down Expand Up @@ -712,6 +744,30 @@ - (void)verifyAppStorePurchase:(nonnull ADJAppStorePurchase *)purchase
withCompletionHandler:completion];
}

- (void)enableCoppaComplianceInDelay {
if (![self checkActivityHandler:@"enable coppa compliance in delay"]) {
return;
}

[self.activityHandler setCoppaComplianceInDelay:YES];
}

- (void)disableCoppaComplianceInDelay {
if (![self checkActivityHandler:@"disable coppa compliance in delay"]) {
return;
}

[self.activityHandler setCoppaComplianceInDelay:NO];
}

- (void)setExternalDeviceIdInDelay:(nullable NSString *)externalDeviceId {
if (![self checkActivityHandler:@"set external device id in delay"]) {
return;
}

[self.activityHandler setExternalDeviceIdInDelay:externalDeviceId];
}

- (void)verifyAndTrackAppStorePurchase:(nonnull ADJEvent *)event
withCompletionHandler:(void (^_Nonnull)(ADJPurchaseVerificationResult * _Nonnull verificationResult))completion {
if (![self checkActivityHandler]) {
Expand All @@ -727,6 +783,14 @@ - (void)verifyAndTrackAppStorePurchase:(nonnull ADJEvent *)event
[self.activityHandler verifyAndTrackAppStorePurchase:event withCompletionHandler:completion];
}

- (void)endFirstSessionDelay {
if (![self checkActivityHandler]) {
return;
}

[self.activityHandler endFirstSessionDelay];
}

- (void)teardown {
if (self.activityHandler == nil) {
[self.logger error:@"Adjust already down or not initialized"];
Expand Down
29 changes: 27 additions & 2 deletions Adjust/Internal/ADJActivityHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,10 @@
@property (nonatomic, strong) NSMutableArray * _Nullable preLaunchActionsArray;
@property (nonatomic, strong) NSMutableArray * _Nullable cachedAttributionReadCallbacksArray;
@property (nonatomic, strong) NSMutableArray * _Nullable cachedAdidReadCallbacksArray;

@property (nonatomic, copy) NSNumber *_Nullable enabled;
@property (nonatomic, assign) BOOL offline;
@property (nonatomic, copy) NSString *_Nullable extraPath;
@property (nonatomic, strong) NSMutableArray *_Nullable preLaunchAdjustThirdPartySharingArray;
@property (nonatomic, copy) NSNumber *_Nullable lastMeasurementConsentTracked;

- (nonnull id)init;

Expand Down Expand Up @@ -109,10 +108,14 @@
withCompletionHandler:(nonnull ADJVerificationResultBlock)completion;
- (void)attributionWithCompletionHandler:(nonnull ADJAttributionGetterBlock)completion;
- (void)adidWithCompletionHandler:(nonnull ADJAdidGetterBlock)completion;
- (void)setCoppaComplianceInDelay:(BOOL)isCoppaComplianceEnabled;
- (void)setExternalDeviceIdInDelay:(nullable NSString *)externalDeviceId;
- (void)verifyAndTrackAppStorePurchase:(nonnull ADJEvent *)event
withCompletionHandler:(nonnull ADJVerificationResultBlock)completion;
- (void)invokeClientSkanUpdateCallbackWithResult:(NSDictionary * _Nonnull)result;

- (void)endFirstSessionDelay;

- (ADJPackageParams * _Nullable)packageParams;
- (ADJActivityState * _Nullable)activityState;
- (ADJConfig * _Nullable)adjustConfig;
Expand Down Expand Up @@ -140,6 +143,28 @@
forKey:(NSString *_Nonnull)key;
- (void)removeGlobalCallbackParametersI:(ADJActivityHandler *_Nonnull)selfI;
- (void)removeGlobalPartnerParametersI:(ADJActivityHandler *_Nonnull)selfI;

- (void)tryTrackThirdPartySharingI:(nonnull ADJThirdPartySharing *)thirdPartySharing;
- (void)tryTrackMeasurementConsentI:(BOOL)enabled;
@end


@interface ADJFirstSessionDelayManager : NSObject

- (nonnull instancetype)initWithActivityHandler:(ADJActivityHandler * _Nonnull)activityHandler;

- (void)delayOrInitWithBlock:(void (^_Nonnull)(ADJActivityHandler *_Nonnull selfI, BOOL isInactive))initBlock;
- (void)endFirstSessionDelay;
- (void)setCoppaComplianceInDelay:(BOOL)isCoppaComplianceEnabled;
- (void)setExternalDeviceIdInDelay:(NSString * _Nullable)externalDeviceId;
- (void)processApiAction:(NSString * _Nonnull)actionName
isPreLaunch:(BOOL)isPreLaunch
withBlock:(void (^_Nonnull)(_Nonnull id))selfInjectedBlock;



- (BOOL)wasSet;

@end

@interface ADJTrackingStatusManager : NSObject
Expand Down
Loading