From 5af20acaac0ed4cff53141f8249b5de2200f3a9d Mon Sep 17 00:00:00 2001 From: Genady Buchatsky Date: Thu, 9 Jun 2022 13:17:40 +0200 Subject: [PATCH 01/17] refac: adds error handling, logging, string constants --- .../Classes/AdjustAdobeExtension.m | 100 ++++++++++-------- .../AdjustAdobeExtensionEventListener.h | 3 + .../AdjustAdobeExtensionSharedStateListener.h | 3 + .../AdjustAdobeExtensionSharedStateListener.m | 40 ++++--- Example/Podfile.lock | 14 +-- 5 files changed, 99 insertions(+), 61 deletions(-) diff --git a/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m b/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m index 5cf4930..99ef901 100644 --- a/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m +++ b/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m @@ -11,8 +11,8 @@ #import "AdjustAdobeExtensionEventListener.h" NSString * const ADJAdobeExtensionLogTag = @"AdjustAdobeExtension"; +NSString * const ADJAdobeExtensionName = @"com.adjust.adobeextension"; NSString * const ADJAdobeExtensionSdkPrefix = @"adobe_ext1.0.4"; - NSString * const ADJAdobeAdjustEventToken = @"adj.eventToken"; NSString * const ADJAdobeAdjustEventCurrency = @"adj.currency"; NSString * const ADJAdobeAdjustEventRevenue = @"adj.revenue"; @@ -41,43 +41,37 @@ - (instancetype)init { // Shared State listener if ([self.api registerListener:[AdjustAdobeExtensionSharedStateListener class] - eventType:@"com.adobe.eventType.hub" - eventSource:@"com.adobe.eventSource.sharedState" + eventType:ADJAdobeEventTypeHub + eventSource:ADJAdobeEventSourceSharedState error:&error]) { - [ACPCore log:ACPMobileLogLevelDebug tag:ADJAdobeExtensionLogTag - message:@"successfully registered for Event Hub Shared State events"]; - } else if (error) { - [ACPCore log:ACPMobileLogLevelError + [ACPCore log:ACPMobileLogLevelDebug tag:ADJAdobeExtensionLogTag - message:[NSString stringWithFormat: - @"An error occured while" - " registering AdjustAdobeExtensionSharedStateListener, error code: %ld", - (long)[error code]]]; + message:@"Successfully registered Extension Listener for Event Hub Shared State events."]; } else { [ACPCore log:ACPMobileLogLevelError tag:ADJAdobeExtensionLogTag message:[NSString stringWithFormat: - @"An error occured while" - " registering AdjustAdobeExtensionSharedStateListener, without error code"]]; + @"An error occured while registering Extension Listener" + " for Event Hub Shared State events. %@", + (error) ? [NSString stringWithFormat:@"Code: %ld, Domain: %@, Description: %@.", (long)error.code, error.domain, error.localizedDescription ] : + @"Unknown error."]]; } if ([self.api registerListener:[AdjustAdobeExtensionEventListener class] - eventType:@"com.adobe.eventType.generic.track" - eventSource:@"com.adobe.eventSource.requestContent" + eventType:ADJAdobeEventTypeGenericTrack + eventSource:ADJAdobeEventSourceRequestContent error:&error]) { - [ACPCore log:ACPMobileLogLevelDebug tag:ADJAdobeExtensionLogTag - message:@"Successfully registered for Extension Request Content events"]; - } else if (error) { - [ACPCore log:ACPMobileLogLevelError tag:ADJAdobeExtensionLogTag - message:[NSString stringWithFormat: - @"There was an error registering ExtensionListener" - " for Extension Request Content events: %@", - error.localizedDescription ?: @"unknown"]]; + [ACPCore log:ACPMobileLogLevelDebug + tag:ADJAdobeExtensionLogTag + message:@"Successfully registered Extension Listener for Extension Request Content events"]; } else { - [ACPCore log:ACPMobileLogLevelError tag:ADJAdobeExtensionLogTag + [ACPCore log:ACPMobileLogLevelError + tag:ADJAdobeExtensionLogTag message:[NSString stringWithFormat: - @"There was an error registering ExtensionListener" - " for Extension Request Content events, without error code"]]; + @"An error occured while registering Extension Listener" + " for Extension Request Content events: %@", + (error) ? [NSString stringWithFormat:@"Code: %ld, Domain: %@, Description: %@.", (long)error.code, error.domain, error.localizedDescription ] : + @"Unknown error."]]; } return self; @@ -85,25 +79,30 @@ - (instancetype)init { - (void)handleEventData:(nullable NSDictionary *)eventData { if (eventData == nil) { - return; - } - - if (!self.sdkInitialized) { - [self.receivedEvents addObject:eventData]; + [ACPCore log:ACPMobileLogLevelError + tag:ADJAdobeExtensionLogTag + message:@"Extension event error: eventData is nil!"]; return; } NSDictionary *contextdata = eventData[@"contextdata"]; if (contextdata == nil) { + [ACPCore log:ACPMobileLogLevelError + tag:ADJAdobeExtensionLogTag + message:@"Extension event error: contextdata is nil!"]; return; } NSString *adjEventToken = contextdata[ADJAdobeAdjustEventToken]; - if (adjEventToken == nil) { return; } + if (!self.sdkInitialized) { + [self.receivedEvents addObject:eventData]; + return; + } + ADJEvent *event = [ADJEvent eventWithEventToken:adjEventToken]; NSString *currency = contextdata[ADJAdobeAdjustEventCurrency]; NSNumber *revenue = contextdata[ADJAdobeAdjustEventRevenue]; @@ -119,7 +118,7 @@ - (void)setupAdjustWithAppToken:(NSString *)appToken trackAttribution:(BOOL)trac if (!_configInstance) { [ACPCore log:ACPMobileLogLevelError tag:ADJAdobeExtensionLogTag - message:@"Extension should be registered first"]; + message:@"Extension should be registered first!"]; return; } @@ -170,23 +169,40 @@ - (void)dumpReceivedEvents { } + (void)registerExtensionWithConfig:(AdjustAdobeExtensionConfig *)config { + + if (config == nil) { + [ACPCore log:ACPMobileLogLevelError + tag:ADJAdobeExtensionLogTag + message:@"AdjustExtension registration error: config is nil!"]; + return; + } + + if (config.environment == nil || config.environment.length == 0) { + [ACPCore log:ACPMobileLogLevelError + tag:ADJAdobeExtensionLogTag + message:@"AdjustExtension registration error: Environment is empty! Use ADJEnvironmentSandbox or ADJEnvironmentProduction."]; + return; + } + NSError *error = nil; if ([ACPCore registerExtension:[AdjustAdobeExtension class] error:&error]) { - [ACPCore log:ACPMobileLogLevelDebug tag:ADJAdobeExtensionLogTag - message:@"Successfully registered AdjustExtension"]; + [ACPCore log:ACPMobileLogLevelDebug + tag:ADJAdobeExtensionLogTag + message:@"Successfully registered Adjust Extension"]; _configInstance = config; - } else if (error) { - [ACPCore log:ACPMobileLogLevelError tag:ADJAdobeExtensionLogTag - message:[NSString stringWithFormat:@"Error registering AdjustExtension: %@ %d", - [error domain], (int)[error code]]]; } else { - [ACPCore log:ACPMobileLogLevelError tag:ADJAdobeExtensionLogTag - message:[NSString stringWithFormat:@"Error registering AdjustExtension, without error code"]]; + [ACPCore log:ACPMobileLogLevelError + tag:ADJAdobeExtensionLogTag + // message:[NSString stringWithFormat:@"Error registering AdjustExtension: %@ %d", + message:[NSString stringWithFormat: + @"An error occured while registering Adjust Extension: %@", + (error) ? [NSString stringWithFormat:@"Code: %ld, Domain: %@, Description: %@.", (long)error.code, error.domain, error.localizedDescription ] : + @"Unknown error."]]; } } - (nullable NSString *)name { - return @"com.adjust.adobeextension"; + return ADJAdobeExtensionName; } - (nullable NSString *)version { diff --git a/AdjustAdobeExtension/Classes/AdjustAdobeExtensionEventListener.h b/AdjustAdobeExtension/Classes/AdjustAdobeExtensionEventListener.h index c1de06f..8e261bb 100644 --- a/AdjustAdobeExtension/Classes/AdjustAdobeExtensionEventListener.h +++ b/AdjustAdobeExtension/Classes/AdjustAdobeExtensionEventListener.h @@ -12,6 +12,9 @@ NS_ASSUME_NONNULL_BEGIN +extern NSString * const ADJAdobeEventTypeGenericTrack; +extern NSString * const ADJAdobeEventSourceRequestContent; + @interface AdjustAdobeExtensionEventListener : ACPExtensionListener - (void)hear:(nonnull ACPExtensionEvent *)event; diff --git a/AdjustAdobeExtension/Classes/AdjustAdobeExtensionSharedStateListener.h b/AdjustAdobeExtension/Classes/AdjustAdobeExtensionSharedStateListener.h index 9936045..af4f55b 100644 --- a/AdjustAdobeExtension/Classes/AdjustAdobeExtensionSharedStateListener.h +++ b/AdjustAdobeExtension/Classes/AdjustAdobeExtensionSharedStateListener.h @@ -12,6 +12,9 @@ NS_ASSUME_NONNULL_BEGIN +extern NSString * const ADJAdobeEventTypeHub; +extern NSString * const ADJAdobeEventSourceSharedState; + @interface AdjustAdobeExtensionSharedStateListener : ACPExtensionListener - (void)hear:(ACPExtensionEvent *)event; diff --git a/AdjustAdobeExtension/Classes/AdjustAdobeExtensionSharedStateListener.m b/AdjustAdobeExtension/Classes/AdjustAdobeExtensionSharedStateListener.m index c3ddd0b..eebbc02 100644 --- a/AdjustAdobeExtension/Classes/AdjustAdobeExtensionSharedStateListener.m +++ b/AdjustAdobeExtension/Classes/AdjustAdobeExtensionSharedStateListener.m @@ -11,6 +11,8 @@ #import NSString * const ADJAdobeModuleConfiguration = @"com.adobe.module.configuration"; +NSString * const ADJAdobeEventTypeHub = @"com.adobe.eventType.hub"; +NSString * const ADJAdobeEventSourceSharedState = @"com.adobe.eventSource.sharedState"; NSString * const ADJConfigurationAppToken = @"adjustAppToken"; NSString * const ADJConfigurationTrackAttribution = @"adjustTrackAttribution"; @@ -21,6 +23,9 @@ - (void)hear:(ACPExtensionEvent *)event { NSDictionary *eventData = [event eventData]; if (!eventData) { + [ACPCore log:ACPMobileLogLevelError + tag:ADJAdobeExtensionLogTag + message:@"Extension eventData is nil!"]; return; } if (![eventData[@"stateowner"] isEqualToString:ADJAdobeModuleConfiguration]) { @@ -28,34 +33,45 @@ - (void)hear:(ACPExtensionEvent *)event { } NSError *error = nil; - NSDictionary *configSharedState = - [self.extension.api getSharedEventState:ADJAdobeModuleConfiguration event:event error:&error]; + NSDictionary *configSharedState = [self.extension.api getSharedEventState:ADJAdobeModuleConfiguration + event:event + error:&error]; + if (configSharedState == nil || error) { + [ACPCore log:ACPMobileLogLevelError + tag:ADJAdobeExtensionLogTag + message:[NSString stringWithFormat: + @"An error occured while calling getSharedEventState: %@", + (error) ? [NSString stringWithFormat:@"Code: %ld, Domain: %@, Description: %@.", (long)error.code, error.domain, error.localizedDescription ] : + @"Unknown error."]]; + return; + } - if (error) { + NSString *adjustAppToken = [configSharedState objectForKey:ADJConfigurationAppToken]; + if (adjustAppToken == nil) { [ACPCore log:ACPMobileLogLevelError tag:ADJAdobeExtensionLogTag - message:[NSString stringWithFormat:@"Error on getSharedEventState %@:%zd.", - [error domain], - [error code]]]; + message:@"Extension module configuration error: Adjust App Token is nil!"]; return; } - NSString *adjustAppToken = [configSharedState objectForKey:ADJConfigurationAppToken]; id adjustTrackAttribution = [configSharedState objectForKey:ADJConfigurationTrackAttribution]; - - if (adjustAppToken == nil || adjustTrackAttribution == nil) { + if (adjustTrackAttribution == nil) { + [ACPCore log:ACPMobileLogLevelError + tag:ADJAdobeExtensionLogTag + message:@"Extension module configuration error: Adjust Trak Attribution is nil!"]; return; } if (![self.extension isKindOfClass:[AdjustAdobeExtension class]]) { + [ACPCore log:ACPMobileLogLevelError + tag:ADJAdobeExtensionLogTag + message:@"Extension type is not AdjustAdobeExtension!"]; return; } AdjustAdobeExtension *adjExt = (AdjustAdobeExtension *)[self extension]; - BOOL shouldTrackAttribution = - [adjustTrackAttribution isKindOfClass:[NSNumber class]] - && [adjustTrackAttribution integerValue] == 1; + [adjustTrackAttribution isKindOfClass:[NSNumber class]] && [adjustTrackAttribution integerValue] == 1; [adjExt setupAdjustWithAppToken:adjustAppToken trackAttribution:shouldTrackAttribution]; } diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 3773ed7..65f9a43 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -12,12 +12,12 @@ PODS: - ACPUserProfile/xcframeworks (= 2.2.0) - ACPUserProfile/xcframeworks (2.2.0): - ACPCore (>= 2.9.0) - - Adjust (4.29.7): - - Adjust/Core (= 4.29.7) - - Adjust/Core (4.29.7) - - AdjustAdobeExtension (1.0.3): + - Adjust (4.30.0): + - Adjust/Core (= 4.30.0) + - Adjust/Core (4.30.0) + - AdjustAdobeExtension (1.0.4): - ACPCore - - Adjust (= 4.29.7) + - Adjust (= 4.30.0) DEPENDENCIES: - ACPCore (~> 2.0) @@ -40,8 +40,8 @@ SPEC CHECKSUMS: ACPCore: f6c5ec32fe162e61a18bec2ae79c8c5a48362a46 ACPGriffon: 5b46aa44e9667b1ff5d35aa37a84992b58d2aadf ACPUserProfile: 34bd51d00a2ae1add3d04eab0a313b73cb01b904 - Adjust: 91a06a01e4bb35b432e26b5d5bb8995b95fc381c - AdjustAdobeExtension: 97a4e60f2aab26c4c0093bca6588e4992286d44e + Adjust: 6ed5493e91e9a77f6515d94f640bb72506a06b9d + AdjustAdobeExtension: 809dd9ddd0d8c65f1e0370b15dd21b45c9c708be PODFILE CHECKSUM: 9d0e231ac981dcf17cb67e756778f0a8f6f6332c From f740343acb2e5b61e9788abf5c7f37c2acfb2994 Mon Sep 17 00:00:00 2001 From: Genady Buchatsky Date: Mon, 27 Jun 2022 13:38:45 +0200 Subject: [PATCH 02/17] perf: add synchronization logic --- .../Classes/AdjustAdobeExtension.m | 189 +++++++++--------- 1 file changed, 95 insertions(+), 94 deletions(-) diff --git a/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m b/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m index 99ef901..3083835 100644 --- a/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m +++ b/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m @@ -16,6 +16,7 @@ NSString * const ADJAdobeAdjustEventToken = @"adj.eventToken"; NSString * const ADJAdobeAdjustEventCurrency = @"adj.currency"; NSString * const ADJAdobeAdjustEventRevenue = @"adj.revenue"; +char * const kQUEUE_ID_SYNC = "com.adjust.AdjustAdobeExtension.sync_queue"; static AdjustAdobeExtensionConfig *_configInstance = nil; @@ -23,11 +24,44 @@ @interface AdjustAdobeExtension() @property (nonatomic, assign) BOOL sdkInitialized; @property (nonatomic, strong) NSMutableArray *receivedEvents; +@property (nonatomic, strong) dispatch_queue_t syncQueue; @end @implementation AdjustAdobeExtension ++ (void)registerExtensionWithConfig:(AdjustAdobeExtensionConfig *)config { + + if (config == nil) { + [ACPCore log:ACPMobileLogLevelError + tag:ADJAdobeExtensionLogTag + message:@"AdjustExtension registration error: config is nil!"]; + return; + } + + if (config.environment == nil || config.environment.length == 0) { + [ACPCore log:ACPMobileLogLevelError + tag:ADJAdobeExtensionLogTag + message:@"AdjustExtension registration error: Environment is empty! Use ADJEnvironmentSandbox or ADJEnvironmentProduction."]; + return; + } + + NSError *error = nil; + if ([ACPCore registerExtension:[AdjustAdobeExtension class] error:&error]) { + [ACPCore log:ACPMobileLogLevelDebug + tag:ADJAdobeExtensionLogTag + message:@"Successfully registered Adjust Extension"]; + _configInstance = config; + } else { + [ACPCore log:ACPMobileLogLevelError + tag:ADJAdobeExtensionLogTag + message:[NSString stringWithFormat: + @"An error occured while registering Adjust Extension: %@", + (error) ? [NSString stringWithFormat:@"Code: %ld, Domain: %@, Description: %@.", (long)error.code, error.domain, error.localizedDescription ] : + @"Unknown error."]]; + } +} + - (instancetype)init { self = [super init]; if (self == nil) { @@ -36,6 +70,7 @@ - (instancetype)init { _sdkInitialized = NO; _receivedEvents = [NSMutableArray array]; + _syncQueue = dispatch_queue_create(kQUEUE_ID_SYNC, DISPATCH_QUEUE_SERIAL); NSError *error = nil; @@ -57,6 +92,7 @@ - (instancetype)init { @"Unknown error."]]; } + // Events listener if ([self.api registerListener:[AdjustAdobeExtensionEventListener class] eventType:ADJAdobeEventTypeGenericTrack eventSource:ADJAdobeEventSourceRequestContent @@ -77,14 +113,72 @@ - (instancetype)init { return self; } +- (void)setupAdjustWithAppToken:(NSString *)appToken trackAttribution:(BOOL)trackAttribution { + + dispatch_async(self.syncQueue, ^{ + + if (!_configInstance) { + [ACPCore log:ACPMobileLogLevelError + tag:ADJAdobeExtensionLogTag + message:@"Extension should be registered first!"]; + return; + } + + if (self.sdkInitialized == YES) { + return; + } + + self.sdkInitialized = YES; + + _configInstance.shouldTrackAttribution = trackAttribution; + ADJConfig *adjustConfig = [ADJConfig configWithAppToken:appToken + environment:_configInstance.environment]; + [adjustConfig setSdkPrefix:ADJAdobeExtensionSdkPrefix]; + [adjustConfig setDelegate:self]; + + switch ([ACPCore logLevel]) { + case ACPMobileLogLevelError: + [adjustConfig setLogLevel:ADJLogLevelError]; + break; + case ACPMobileLogLevelWarning: + [adjustConfig setLogLevel:ADJLogLevelWarn]; + break; + case ACPMobileLogLevelDebug: + [adjustConfig setLogLevel:ADJLogLevelDebug]; + break; + case ACPMobileLogLevelVerbose: + [adjustConfig setLogLevel:ADJLogLevelVerbose]; + break; + } + + [Adjust appDidLaunch:adjustConfig]; + + for (NSDictionary *event in self.receivedEvents) { + [self processEvent:event]; + } + [self.receivedEvents removeAllObjects]; + }); +} + - (void)handleEventData:(nullable NSDictionary *)eventData { + dispatch_async(self.syncQueue, ^{ + if (!self.sdkInitialized) { + [self.receivedEvents addObject:eventData]; + } else { + [self processEvent:eventData]; + } + }); +} + +- (void)processEvent:(nullable NSDictionary *)eventData { + if (eventData == nil) { [ACPCore log:ACPMobileLogLevelError tag:ADJAdobeExtensionLogTag message:@"Extension event error: eventData is nil!"]; return; } - + NSDictionary *contextdata = eventData[@"contextdata"]; if (contextdata == nil) { [ACPCore log:ACPMobileLogLevelError @@ -98,11 +192,6 @@ - (void)handleEventData:(nullable NSDictionary *)eventData { return; } - if (!self.sdkInitialized) { - [self.receivedEvents addObject:eventData]; - return; - } - ADJEvent *event = [ADJEvent eventWithEventToken:adjEventToken]; NSString *currency = contextdata[ADJAdobeAdjustEventCurrency]; NSNumber *revenue = contextdata[ADJAdobeAdjustEventRevenue]; @@ -110,97 +199,9 @@ - (void)handleEventData:(nullable NSDictionary *)eventData { if (currency && revenue) { [event setRevenue:[revenue doubleValue] currency:currency]; } - [Adjust trackEvent:event]; } -- (void)setupAdjustWithAppToken:(NSString *)appToken trackAttribution:(BOOL)trackAttribution { - if (!_configInstance) { - [ACPCore log:ACPMobileLogLevelError - tag:ADJAdobeExtensionLogTag - message:@"Extension should be registered first!"]; - return; - } - - if (self.sdkInitialized) { - return; - } - - _configInstance.shouldTrackAttribution = trackAttribution; - - ADJConfig *adjustConfig = [ADJConfig configWithAppToken:appToken - environment:_configInstance.environment]; - [adjustConfig setSdkPrefix:ADJAdobeExtensionSdkPrefix]; - [adjustConfig setDelegate:self]; - - switch ([ACPCore logLevel]) { - case ACPMobileLogLevelError: - [adjustConfig setLogLevel:ADJLogLevelError]; - break; - case ACPMobileLogLevelWarning: - [adjustConfig setLogLevel:ADJLogLevelWarn]; - break; - case ACPMobileLogLevelDebug: - [adjustConfig setLogLevel:ADJLogLevelDebug]; - break; - case ACPMobileLogLevelVerbose: - [adjustConfig setLogLevel:ADJLogLevelVerbose]; - break; - } - - [Adjust appDidLaunch:adjustConfig]; - - self.sdkInitialized = YES; - [self dumpReceivedEvents]; -} - -- (void)dumpReceivedEvents { - if (self.receivedEvents.count <= 0) { - return; - } - - // dump events received before initialization - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ - for (NSDictionary *event in self.receivedEvents) { - [self handleEventData:event]; - } - [self.receivedEvents removeAllObjects]; - }); -} - -+ (void)registerExtensionWithConfig:(AdjustAdobeExtensionConfig *)config { - - if (config == nil) { - [ACPCore log:ACPMobileLogLevelError - tag:ADJAdobeExtensionLogTag - message:@"AdjustExtension registration error: config is nil!"]; - return; - } - - if (config.environment == nil || config.environment.length == 0) { - [ACPCore log:ACPMobileLogLevelError - tag:ADJAdobeExtensionLogTag - message:@"AdjustExtension registration error: Environment is empty! Use ADJEnvironmentSandbox or ADJEnvironmentProduction."]; - return; - } - - NSError *error = nil; - if ([ACPCore registerExtension:[AdjustAdobeExtension class] error:&error]) { - [ACPCore log:ACPMobileLogLevelDebug - tag:ADJAdobeExtensionLogTag - message:@"Successfully registered Adjust Extension"]; - _configInstance = config; - } else { - [ACPCore log:ACPMobileLogLevelError - tag:ADJAdobeExtensionLogTag - // message:[NSString stringWithFormat:@"Error registering AdjustExtension: %@ %d", - message:[NSString stringWithFormat: - @"An error occured while registering Adjust Extension: %@", - (error) ? [NSString stringWithFormat:@"Code: %ld, Domain: %@, Description: %@.", (long)error.code, error.domain, error.localizedDescription ] : - @"Unknown error."]]; - } -} - - (nullable NSString *)name { return ADJAdobeExtensionName; } From 580292755216965d6272f0dc56a4811d9a5ed664 Mon Sep 17 00:00:00 2001 From: Genady Buchatsky Date: Tue, 5 Jul 2022 13:25:11 +0200 Subject: [PATCH 03/17] feat: add push token, track callback/partner params --- .../Classes/AdjustAdobeExtension.h | 15 +++- .../Classes/AdjustAdobeExtension.m | 84 +++++++++++++++++-- .../AdjustAdobeExtension/ADJViewController.m | 42 ++++++++-- 3 files changed, 123 insertions(+), 18 deletions(-) diff --git a/AdjustAdobeExtension/Classes/AdjustAdobeExtension.h b/AdjustAdobeExtension/Classes/AdjustAdobeExtension.h index 8796518..5acdae0 100644 --- a/AdjustAdobeExtension/Classes/AdjustAdobeExtension.h +++ b/AdjustAdobeExtension/Classes/AdjustAdobeExtension.h @@ -20,11 +20,22 @@ NS_ASSUME_NONNULL_BEGIN +extern NSString * const ADJAdobeExtensionLogTag; +extern NSString * const ADJAdobeExtensionSdkPrefix; + +extern NSString * const ADJAdobeAdjustActionTrackEvent; +extern NSString * const ADJAdobeAdjustActionSetPushToken; + extern NSString * const ADJAdobeAdjustEventToken; extern NSString * const ADJAdobeAdjustEventCurrency; extern NSString * const ADJAdobeAdjustEventRevenue; -extern NSString * const ADJAdobeExtensionLogTag; -extern NSString * const ADJAdobeExtensionSdkPrefix; +extern NSString * const ADJAdobeAdjustEventCallbackParamPrefix; +extern NSString * const ADJAdobeAdjustEventPartnerParamPrefix; + +extern NSString * const ADJAdobeAdjustPushToken; + + + @interface AdjustAdobeExtension : ACPExtension diff --git a/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m b/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m index 3083835..91135a2 100644 --- a/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m +++ b/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m @@ -13,11 +13,24 @@ NSString * const ADJAdobeExtensionLogTag = @"AdjustAdobeExtension"; NSString * const ADJAdobeExtensionName = @"com.adjust.adobeextension"; NSString * const ADJAdobeExtensionSdkPrefix = @"adobe_ext1.0.4"; +NSString * const ADJAdobeEventDataKeyAction = @"action"; +NSString * const ADJAdobeEventDataKeyContextData = @"contextdata"; + +// Action types +NSString * const ADJAdobeAdjustActionTrackEvent = @"adj.trackEvent"; +NSString * const ADJAdobeAdjustActionSetPushToken = @"adj.setPushToken"; + +// Adjust Event NSString * const ADJAdobeAdjustEventToken = @"adj.eventToken"; NSString * const ADJAdobeAdjustEventCurrency = @"adj.currency"; NSString * const ADJAdobeAdjustEventRevenue = @"adj.revenue"; -char * const kQUEUE_ID_SYNC = "com.adjust.AdjustAdobeExtension.sync_queue"; +NSString * const ADJAdobeAdjustEventCallbackParamPrefix = @"adj.event.callback."; +NSString * const ADJAdobeAdjustEventPartnerParamPrefix = @"adj.event.partner."; + +// Push token +NSString * const ADJAdobeAdjustPushToken = @"adj.pushToken"; +char * const kQUEUE_ID_SYNC = "com.adjust.AdjustAdobeExtension.sync_queue"; static AdjustAdobeExtensionConfig *_configInstance = nil; @interface AdjustAdobeExtension() @@ -25,6 +38,9 @@ @interface AdjustAdobeExtension() @property (nonatomic, assign) BOOL sdkInitialized; @property (nonatomic, strong) NSMutableArray *receivedEvents; @property (nonatomic, strong) dispatch_queue_t syncQueue; +@property (nonatomic,strong) NSNumber *numNan; +@property (nonatomic,strong) NSNumber *numPlusInf; +@property (nonatomic,strong) NSNumber *numMinusInf; @end @@ -72,8 +88,14 @@ - (instancetype)init { _receivedEvents = [NSMutableArray array]; _syncQueue = dispatch_queue_create(kQUEUE_ID_SYNC, DISPATCH_QUEUE_SERIAL); - NSError *error = nil; + double dblZero = 0.0; + double dblPlusOne = 1.0; + double dblMinusOne = -1.0; + _numPlusInf = [NSNumber numberWithDouble:dblPlusOne/dblZero]; + _numMinusInf = [NSNumber numberWithDouble:dblMinusOne/dblZero]; + _numNan = [NSNumber numberWithDouble:sqrt(dblMinusOne)]; + NSError *error = nil; // Shared State listener if ([self.api registerListener:[AdjustAdobeExtensionSharedStateListener class] eventType:ADJAdobeEventTypeHub @@ -179,7 +201,8 @@ - (void)processEvent:(nullable NSDictionary *)eventData { return; } - NSDictionary *contextdata = eventData[@"contextdata"]; + NSString *action = eventData[ADJAdobeEventDataKeyAction]; + NSDictionary *contextdata = eventData[ADJAdobeEventDataKeyContextData]; if (contextdata == nil) { [ACPCore log:ACPMobileLogLevelError tag:ADJAdobeExtensionLogTag @@ -187,18 +210,63 @@ - (void)processEvent:(nullable NSDictionary *)eventData { return; } - NSString *adjEventToken = contextdata[ADJAdobeAdjustEventToken]; + if (action.length > 0 && + [action compare:ADJAdobeAdjustActionSetPushToken options:NSCaseInsensitiveSearch] == NSOrderedSame) { + [self setPushToken:contextdata]; + } else { + [self trackEvent:contextdata]; + } +} + +- (void)setPushToken:(NSDictionary *)contextData { + NSString *pushToken = contextData[ADJAdobeAdjustPushToken]; + if (pushToken != nil && pushToken.length > 0) { + [Adjust setPushToken:pushToken]; + } else { + [ACPCore log:ACPMobileLogLevelError + tag:ADJAdobeExtensionLogTag + message:@"PushToken is nil or zero-length!"]; + } +} + +- (void)trackEvent:(NSDictionary *)contextData { + + NSString *adjEventToken = contextData[ADJAdobeAdjustEventToken]; if (adjEventToken == nil) { return; } ADJEvent *event = [ADJEvent eventWithEventToken:adjEventToken]; - NSString *currency = contextdata[ADJAdobeAdjustEventCurrency]; - NSNumber *revenue = contextdata[ADJAdobeAdjustEventRevenue]; + NSString *currency = contextData[ADJAdobeAdjustEventCurrency]; + NSString *revenue = contextData[ADJAdobeAdjustEventRevenue]; + + // Revenue data + if (currency != nil && currency.length > 0 && revenue != nil && revenue.length > 0) { + NSNumber *numRevenue = [NSNumber numberWithDouble:[revenue doubleValue]]; + if ([numRevenue isEqualToNumber:self.numNan] || + [numRevenue isEqualToNumber:self.numPlusInf] || + [numRevenue isEqualToNumber:self.numMinusInf]) { + [ACPCore log:ACPMobileLogLevelError + tag:ADJAdobeExtensionLogTag + message:@"Revenue number is malformed!"]; + return; + } else { + [event setRevenue:[numRevenue doubleValue] currency:currency]; + } + } - if (currency && revenue) { - [event setRevenue:[revenue doubleValue] currency:currency]; + // Callback / Partner Params + NSArray *allKeys = contextData.allKeys; + for (NSString *key in allKeys) { + if ([key hasPrefix:ADJAdobeAdjustEventCallbackParamPrefix] == YES) { + NSString *adjKey = [key substringFromIndex:ADJAdobeAdjustEventCallbackParamPrefix.length]; + [event addCallbackParameter:adjKey value:[contextData valueForKey:key]]; + } else if ([key hasPrefix:ADJAdobeAdjustEventPartnerParamPrefix] == YES) { + NSString *adjKey = [key substringFromIndex:ADJAdobeAdjustEventPartnerParamPrefix.length]; + [event addPartnerParameter:adjKey value:[contextData valueForKey:key]]; + } } + [Adjust trackEvent:event]; } diff --git a/Example/AdjustAdobeExtension/ADJViewController.m b/Example/AdjustAdobeExtension/ADJViewController.m index 1bd9e34..ebaf6c5 100644 --- a/Example/AdjustAdobeExtension/ADJViewController.m +++ b/Example/AdjustAdobeExtension/ADJViewController.m @@ -19,14 +19,40 @@ @implementation ADJViewController - (void)viewDidLoad { [super viewDidLoad]; - [ACPCore trackAction:@"TestAction" data:@{@"a": @"b", - ADJAdobeAdjustEventToken: @"g3mfiw"}]; - [ACPCore trackAction:@"TestActionRevenue" data:@{@"a": @"b", - ADJAdobeAdjustEventToken: @"a4fd35", - ADJAdobeAdjustEventRevenue: @"1.0", - ADJAdobeAdjustEventCurrency: @"EUR"}]; - [ACPCore trackState:@"TestState" data:@{@"a": @"b"}]; - + // Track simple event + NSMutableDictionary * dataDict = [NSMutableDictionary dictionary]; + [dataDict setValue:@"g3mfiw" forKey:ADJAdobeAdjustEventToken]; + [ACPCore trackAction:ADJAdobeAdjustActionTrackEvent data:dataDict]; + + [dataDict removeAllObjects]; + + // Track Revenue event + [dataDict setValue:@"a4fd35" forKey:ADJAdobeAdjustEventToken]; + [dataDict setValue:@"1.0" forKey:ADJAdobeAdjustEventRevenue]; + [dataDict setValue:@"EUR" forKey:ADJAdobeAdjustEventCurrency]; + [ACPCore trackAction:ADJAdobeAdjustActionTrackEvent data:dataDict]; + + [dataDict removeAllObjects]; + + // Track event with Callback parameters + [dataDict setValue:@"34vgg9" forKey:ADJAdobeAdjustEventToken]; + [dataDict setValue:@"value1" forKey:[ADJAdobeAdjustEventCallbackParamPrefix stringByAppendingString:@"key1"]]; + [dataDict setValue:@"value2" forKey:[ADJAdobeAdjustEventCallbackParamPrefix stringByAppendingString:@"key2"]]; + [ACPCore trackAction:ADJAdobeAdjustActionTrackEvent data:dataDict]; + + [dataDict removeAllObjects]; + + // Track event with Partner parameters + [dataDict setValue:@"w788qs" forKey:ADJAdobeAdjustEventToken]; + [dataDict setValue:@"value1" forKey:[ADJAdobeAdjustEventPartnerParamPrefix stringByAppendingString:@"key1"]]; + [dataDict setValue:@"value2" forKey:[ADJAdobeAdjustEventPartnerParamPrefix stringByAppendingString:@"key2"]]; + [ACPCore trackAction:ADJAdobeAdjustActionTrackEvent data:dataDict]; + + [dataDict removeAllObjects]; + + // Set Push Token + [dataDict setValue:@"your_app_push_token" forKey:ADJAdobeAdjustPushToken]; + [ACPCore trackAction:ADJAdobeAdjustActionSetPushToken data:dataDict]; } - (void)didReceiveMemoryWarning { From 8c208a92b737d4237003318c9f6196842d199398 Mon Sep 17 00:00:00 2001 From: Genady Buchatsky Date: Fri, 8 Jul 2022 11:48:31 +0200 Subject: [PATCH 04/17] docs: update README --- README.md | 329 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 272 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 2cf6c80..6ad2be0 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,53 @@ # Adjust Extension for Adobe Experience SDK -## Add the Adjust Extension to your project +This is the iOS Adobe Mobile Extension of Adjust™. You can read more about Adjust™ at [adjust.com]. -### Cocoapods integration +## Table of contents -If you're using [CocoaPods](http://cocoapods.org), add the following line to your `Podfile` and continue from [this step](#sdk-integrate): +### [Quick start](#iae-quick-start) + * [Example app](#iae-example-app) + * [Add the Adjust Extension to your project](#iae-sdk-add) + * [Cocoapods integration](#iae-sdk-add-cocoapods) + * [Swift Package Manager integration](#iae-sdk-add-spm) + * [Integrate the Adjust Extension into your app](#iae-sdk-integrate) + * [Basic setup](#iae-basic-setup) + * [Session tracking](#iae-session-tracking) + * [Attribution](#iae-attribution) + * [Add iOS frameworks](#iae-sdk-frameworks) + +### [Events tracking](#iae-tracking) + * [Track event](#iae-track-event) + * [Track revenue](#iae-track-event-revenue) + +### [Custom parameters](#iae-custom-parameters) + * [Custom parameters overview](#iae-custom-parameters-overview) + * [Event parameters](#iae-event-parameters) + * [Event callback parameters](#iae-event-callback-parameters) + * [Event partner parameters](#iae-event-partner-parameters) + +### [Additional features](#iae-additional-features) + * [Attribution callback](#iae-attribution-callback) + * [Deferred deep linking callback](#iae-deferred-deep-linking-callback) + * [Push token (uninstall tracking)](#iae-push-token) + +## Quick start + +### Example app + +There is an example app inside the [Example][example-app] directory. +Please run `pod install` in this folder to build the example application dependencies and then open `AdjustAdobeExtension.xcworkspace` to test the example application. + +## Add the Adjust Extension to your project + +### Cocoapods integration + +If you're using [CocoaPods](http://cocoapods.org), add the following line to your `Podfile` and continue from [this step](#iae-sdk-integrate): ```ruby pod 'AdjustAdobeExtension' ``` -### Swift Package Manager integration +### Swift Package Manager integration If you are using Swift Package Manager, add Adjust Extension for Adobe Experience SDK using the following Github repo link: @@ -23,17 +60,7 @@ Due to a missing SPM support in Adobe ACP SDKs, all required Adobe frameworks ar In the `Frameworks, Libraries, and Embedded Content` section of your App target's `General` tab, add the following frameworks and libraries required for Adobe frameworks: `UIKit`, `SystemConfiguration`, `WebKit`, `UserNotifications`, `libsqlite3.0`, `libc++`, `libz`. -## Add iOS frameworks - -Adjust SDK is able to get additional information in case you link additional iOS frameworks to your app. Please, add following frameworks in case you want to enable Adjust SDK features based on their presence in your app and mark them as optional: - -- `AdSupport.framework` - This framework is needed so that SDK can access to IDFA value and (prior to iOS 14) LAT information. -- `iAd.framework` - This framework is needed so that SDK can automatically handle attribution for ASA campaigns you might be running. -- `AdServices.framework` - For devices running iOS 14.3 or higher, this framework allows the SDK to automatically handle attribution for ASA campaigns. It is required when leveraging the Apple Ads Attribution API. -- `StoreKit.framework` - This framework is needed for access to `SKAdNetwork` framework and for Adjust SDK to handle communication with it automatically in iOS 14 or later. -- `AppTrackingTransparency.framework` - This framework is needed in iOS 14 and later for SDK to be able to wrap user's tracking consent dialog and access to value of the user's consent to be tracked or not. - -## Integrate the Adjust Extension into your app +## Integrate the Adjust Extension into your app Add the following import statement: @@ -47,20 +74,23 @@ Add the following import statement: import AdjustAdobeExtension ``` -## Basic setup +## Basic setup -You don't need to start the Adjust Adjust Extension manually. First, set the configuration in [Launch dashboard](https://launch.adobe.com/) and initialize `ACPCore`, then register the Adjust Extension: +You don't need to start the Adjust Extension manually. First, set the configuration in [Launch dashboard](https://launch.adobe.com/) and initialize `ACPCore`, then register the Adjust Extension: ```objc // Objective-C - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [ACPCore configureWithAppId:@"..."]; - - // ... + + [ACPCore setLogLevel:ACPMobileLogLevelVerbose]; + [ACPCore configureWithAppId:@"{your_adobe_app_id}"]; AdjustAdobeExtensionConfig *config = [AdjustAdobeExtensionConfig configWithEnvironment:ADJEnvironmentSandbox]; [AdjustAdobeExtension registerExtensionWithConfig:config]; - + + [ACPCore start:^{ + [ACPCore lifecycleStart:nil]; + }]; return YES; } ``` @@ -69,77 +99,262 @@ You don't need to start the Adjust Adjust Extension manually. First, set the con // Swift func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - ACPCore.configure(withAppId: "...") - - // ... + ACPCore.setLogLevel(ACPMobileLogLevel.verbose) + ACPCore.configure(withAppId: "{your_adobe_app_id}") if let config = AdjustAdobeExtensionConfig.init(environment: ADJEnvironmentSandbox) { AdjustAdobeExtension.register(with: config) } + ACPCore.start { + ACPCore.lifecycleStart(nil) + } return true } ``` -### Delegates callback +Replace `{your_adobe_app_id}` with your app id from Adobe Launch. + +Next, you must set the `environment` to either sandbox or production mode: + +```objc +ADJEnvironmentSandbox +ADJEnvironmentProduction +``` + +**Important:** Set the value to `ADJEnvironmentSandbox` if (and only if) you or someone else is testing your app. Make sure to set the environment to `ADJEnvironmentProduction` before you publish the app. Set it back to `ADJEnvironmentSandbox` if you start developing and testing it again. + +We use this environment to distinguish between real traffic and test traffic from test devices. Keeping the environment updated according to your current status is very important! + +## Session tracking + +Adjust SDK can track sessions in your app based on Activity lifecycle. + +## Attribution + +The option to share attribution data with Adobe is in the Launch dashboard under the extensions configuration and is on by default. Adjust tracks the action name `Adjust Campaign Data Received` with the following attribution information from Adjust: + +* `Adjust Network` +* `Adjust Campaign` +* `Adjust AdGroup` +* `Adjust Creative` + +## Add iOS frameworks + +Adjust SDK is able to get additional information in case you link additional iOS frameworks to your app. Please, add following frameworks in case you want to enable Adjust SDK features based on their presence in your app and mark them as optional: + +- `AdSupport.framework` - This framework is needed so that SDK can access to IDFA value and (prior to iOS 14) LAT information. +- `iAd.framework` - This framework is needed so that SDK can automatically handle attribution for ASA campaigns you might be running. +- `AdServices.framework` - For devices running iOS 14.3 or higher, this framework allows the SDK to automatically handle attribution for ASA campaigns. It is required when leveraging the Apple Ads Attribution API. +- `StoreKit.framework` - This framework is needed for access to `SKAdNetwork` framework and for Adjust SDK to handle communication with it automatically in iOS 14 or later. +- `AppTrackingTransparency.framework` - This framework is needed in iOS 14 and later for SDK to be able to wrap user's tracking consent dialog and access to value of the user's consent to be tracked or not. + +## Events tracking + +### Track event + +You can use Adobe `[ACPCore trackAction:]` API for [`event tracking`][event-tracking]. Suppose you want to track every tap on a button. To do so, you'll create a new event token in your [dashboard]. Let's say that the event token is `abc123`. In your button's press handling method, add the following lines to track the click: + +```objc +// Objective-C +NSMutableDictionary * dataDict = [NSMutableDictionary dictionary]; +[dataDict setValue:@"abc123" forKey:ADJAdobeAdjustEventToken]; +[ACPCore trackAction:ADJAdobeAdjustActionTrackEvent data:dataDict]; +``` + +```swift +// Swift +var dataDict: Dictionary = [String : String]() +dataDict[ADJAdobeAdjustEventToken] = "abc123" +ACPCore.trackAction(ADJAdobeAdjustActionTrackEvent, data: dataDict) +``` + +### Track revenue -Optional: If you want to receive the attribution and deep link delegates callback, you can register for it in `AdjustAdobeExtensionConfig`: +If your users can generate revenue by tapping on advertisements or making in-app purchases, you can track those revenues too with events. Let's say a tap is worth one Euro cent. You can track the revenue event like this: ```objc // Objective-C -[config callbackDeeplinkResponse:^BOOL(NSURL * _Nullable deeplink) { - // deep link response received +NSMutableDictionary * dataDict = [NSMutableDictionary dictionary]; +[dataDict setValue:@"abc123" forKey:ADJAdobeAdjustEventToken]; +[dataDict setValue:@"0.01" forKey:ADJAdobeAdjustEventRevenue]; +[dataDict setValue:@"EUR" forKey:ADJAdobeAdjustEventCurrency]; +[ACPCore trackAction:ADJAdobeAdjustActionTrackEvent data:dataDict]; +``` - // Apply your logic to determine whether the Adjust SDK should try to open the deep link - return YES; - // or - // return NO; -}]; +```swift +// Swift +var dataDict: Dictionary = [String : String]() +dataDict[ADJAdobeAdjustEventToken] = "abc123" +dataDict[ADJAdobeAdjustEventRevenue] = "0.01" +dataDict[ADJAdobeAdjustEventCurrency] = "EUR" +ACPCore.trackAction(ADJAdobeAdjustActionTrackEvent, data: dataDict) +``` + +## Custom parameters +### Custom parameters overview + +In addition to the data points the Adjust SDK collects by default, you can use the extension to track and add as many custom values as you need (user IDs, product IDs, etc.) to the event or session. Custom parameters are only available as raw data and will **not** appear in your Adjust dashboard. + +You should use **callback parameters** for the values you collect for your own internal use, and **partner parameters** for those you share with external partners. If a value (e.g. product ID) is tracked both for internal use and external partner use, we recommend you track it with both callback and partner parameters. + + +### Event parameters + +### Event callback parameters + +You can register a callback URL for your events in your [dashboard]. We will send a GET request to that URL whenever the event is tracked. You can add callback parameters to that event by adding them as key value pair to the context data map before tracking it. We will then append these parameters to your callback URL. + +For example, if you've registered the URL `http://www.example.com/callback`, then you would track an event like this: + +```objc +// Objective-C +NSMutableDictionary * dataDict = [NSMutableDictionary dictionary]; +[dataDict setValue:@"abc123" forKey:ADJAdobeAdjustEventToken]; +[dataDict setValue:@"value1" forKey:[ADJAdobeAdjustEventCallbackParamPrefix stringByAppendingString:@"key1"]]; +[dataDict setValue:@"value2" forKey:[ADJAdobeAdjustEventCallbackParamPrefix stringByAppendingString:@"key2"]]; +[ACPCore trackAction:ADJAdobeAdjustActionTrackEvent data:dataDict]; +``` + +```swift +// Swift +var dataDict: Dictionary = [String : String]() +dataDict[ADJAdobeAdjustEventToken] = "abc123" +dataDict[ADJAdobeAdjustEventCallbackParamPrefix.appending("key1")] = "value1" +dataDict[ADJAdobeAdjustEventCallbackParamPrefix.appending("key2")] = "value2" +ACPCore.trackAction(ADJAdobeAdjustActionTrackEvent, data: dataDict) +``` + + +In this case we would track the event and send a request to: + +``` +http://www.example.com/callback?key1=value1&key2=value2 +``` + +Adjust supports a variety of placeholders, which can be used as parameter values. In the resulting callback, we would replace the placeholder with an appropriate value. Please note that we don't store any of your custom parameters. We **only** append them to your callbacks. If you haven't registered a callback for an event, we will not even read these parameters. + +You can read more about URL callbacks (including a full list of available values) in our [callbacks guide][callbacks-guide]. + +### Event partner parameters + +When your parameters are activated in the Adjust dashboard, you have the option to transmit them to your network partners. + +This works similarly to the callback parameters mentioned above; + + +```objc +// Objective-C +NSMutableDictionary * dataDict = [NSMutableDictionary dictionary]; +[dataDict setValue:@"abc123" forKey:ADJAdobeAdjustEventToken]; +[dataDict setValue:@"value1" forKey:[ADJAdobeAdjustEventPartnerParamPrefix stringByAppendingString:@"key1"]]; +[dataDict setValue:@"value2" forKey:[ADJAdobeAdjustEventPartnerParamPrefix stringByAppendingString:@"key2"]]; +[ACPCore trackAction:ADJAdobeAdjustActionTrackEvent data:dataDict]; +``` + +```swift +// Swift +var dataDict: Dictionary = [String : String]() +dataDict[ADJAdobeAdjustEventToken] = "abc123" +dataDict[ADJAdobeAdjustEventPartnerParamPrefix.appending("key1")] = "value1" +dataDict[ADJAdobeAdjustEventPartnerParamPrefix.appending("key2")] = "value2" +ACPCore.trackAction(ADJAdobeAdjustActionTrackEvent, data: dataDict) +``` + +You can read more about special partners and these integrations in our [guide to special partners][special-partners]. + +## Additional features + +Once you have integrated the Adjust Extension for Adobe Experience SDK into your project, you can take advantage of the following features: + +### Attribution callback + +You can register a callback code block to be notified of tracker attribution changes. Due to the different sources we consider for attribution, we cannot provide this information synchronously. + +Please see our [attribution data policies][attribution-data] for more information. + +With the extension config instance, add the attribution callback before you start the SDK: + +```objc +// Objective-C +AdjustAdobeExtensionConfig *config = [AdjustAdobeExtensionConfig configWithEnvironment:ADJEnvironmentSandbox]; [config callbackAttributionChanged:^(ADJAttribution * _Nullable attribution) { - // attribution response received + // Attribution response received }]; +[AdjustAdobeExtension registerExtensionWithConfig:config]; ``` ```swift // Swift -config.callbackDeeplinkResponse { (deeplink : URL?) in - // deep link response received +if let config = AdjustAdobeExtensionConfig.init(environment: ADJEnvironmentSandbox) { + config.callbackAttributionChanged { (attribution : ADJAttribution?) in + // Attribution response received + } + AdjustAdobeExtension.register(with: config) +} +``` + +The code block is called after the SDK receives the final attribution data. Within the block body, you'll have an access to the `attribution` parameter. + +### Deferred deep linking callback + +The Adjust SDK opens the deferred deep link by default. There is no extra configuration needed. But if you wish to control whether the Adjust SDK will open the deferred deep link or not, you can do it with a callback code block in the config object. +With the extension config instance, add the deferred deep linking callback block before you start the SDK: + +```objc +// Objective-C +AdjustAdobeExtensionConfig *config = [AdjustAdobeExtensionConfig configWithEnvironment:ADJEnvironmentSandbox]; +[config callbackDeeplinkResponse:^BOOL(NSURL * _Nullable deeplink) { + // Deep link response received // Apply your logic to determine whether the Adjust SDK should try to open the deep link - return true; + return YES; // or - // return false; -} + // return NO; +}]; +[AdjustAdobeExtension registerExtensionWithConfig:config]; +``` -config.callbackAttributionChanged { (attribution : ADJAttribution?) in - // attribution response received +```swift +// Swift +if let config = AdjustAdobeExtensionConfig.init(environment: ADJEnvironmentSandbox) { + config.callbackDeeplinkResponse { (deeplink : URL?) in + // Deep link response received + // Apply your logic to determine whether the Adjust SDK should try to open the deep link + return true; + // or + // return false; + } + AdjustAdobeExtension.register(with: config) } ``` -## Tracking events +After the Adjust SDK receives the deep link information from our backend, the SDK will deliver you its content via the callback block and expect the boolean return value from you. This return value represents your decision on whether or not the Adjust SDK should launch the activity to which you have assigned the scheme name from the deeplink. + +### Push token (uninstall tracking) -Any event (action or state) tracked using `ACPCore` is tracked by Adjust if it contains the `ADJAdobeAdjustEventCurrency` constant as a key: +Push tokens are used for Audience Builder and client callbacks; they are also required for uninstall and reinstall tracking. + +To send us the push notification token, add the following call to Adjust once you have obtained your token (or whenever its value changes): ```objc // Objective-C -[ACPCore trackAction:@"TestAction" data:@{@"a": @"b", ADJAdobeAdjustEventToken: @"abc123"}]; -[ACPCore trackState:@"TestState" data:@{@"a": @"b"}]; // will *not* be tracked by Adjust +NSMutableDictionary * dataDict = [NSMutableDictionary dictionary]; +[dataDict setValue:@"your_app_push_token" forKey:ADJAdobeAdjustPushToken]; +[ACPCore trackAction:ADJAdobeAdjustActionSetPushToken data:dataDict]; ``` ```swift // Swift -ACPCore.trackAction("TestAction", data: ["a": "b", ADJAdobeAdjustEventToken: "abc123"]) -ACPCore.trackState("TestState", data: ["a": "b"]) // will *not* be tracked by Adjust +var dataDict: Dictionary = [String : String]() +dataDict[ADJAdobeAdjustPushToken] = "your_app_push_token" +ACPCore.trackAction(ADJAdobeAdjustActionSetPushToken, data: dataDict) ``` -If the event contains the constants `ADJAdobeAdjustEventCurrency` and `ADJAdobeAdjustEventRevenue` as keys, the event is tracked with this information as well. - -## Attribution - -The option to share attribution data with Adobe is in the Launch dashboard under the extensions configuration and is on by default. Adjust tracks the action name `Adjust Campaign Data Received` with the following attribution information from Adjust: - -* `Adjust Network` -* `Adjust Campaign` -* `Adjust AdGroup` -* `Adjust Creative` +[example-app]: Example/ +[event-tracking]: https://docs.adjust.com/en/event-tracking +[dashboard]: http://dash.adjust.com/ +[callbacks-guide]: https://docs.adjust.com/en/callbacks +[special-partners]: https://docs.adjust.com/en/special-partners +[attribution-data]: https://github.com/adjust/sdks/blob/master/doc/attribution-data.md From 121043c10a1f9ee925a2d2eca2196fa69d84a7ac Mon Sep 17 00:00:00 2001 From: Genady Buchatsky Date: Fri, 8 Jul 2022 11:49:44 +0200 Subject: [PATCH 05/17] chore: update example app --- Example/AdjustAdobeExtension/ADJAppDelegate.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Example/AdjustAdobeExtension/ADJAppDelegate.m b/Example/AdjustAdobeExtension/ADJAppDelegate.m index 6b78a7a..b1523e1 100644 --- a/Example/AdjustAdobeExtension/ADJAppDelegate.m +++ b/Example/AdjustAdobeExtension/ADJAppDelegate.m @@ -25,7 +25,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [ACPCore start:^{ [ACPCore lifecycleStart:nil]; }]; - + return YES; } From 14690b3fa181dcbbbccb2fd7925af7f07f77dba5 Mon Sep 17 00:00:00 2001 From: Genady Buchatsky Date: Fri, 8 Jul 2022 12:45:08 +0200 Subject: [PATCH 06/17] build: update version to 1.1.0 --- AdjustAdobeExtension.podspec | 4 ++-- AdjustAdobeExtension/Classes/AdjustAdobeExtension.m | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/AdjustAdobeExtension.podspec b/AdjustAdobeExtension.podspec index 7c18bbd..6004f54 100644 --- a/AdjustAdobeExtension.podspec +++ b/AdjustAdobeExtension.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = 'AdjustAdobeExtension' - s.version = '1.0.4' + s.version = '1.1.0' s.summary = 'Adjust SDK extension for Adobe Experience Platform.' s.description = <<-DESC A leading attribution solution that brings the full power of mobile ad measurement to your campaigns. @@ -9,7 +9,7 @@ A leading attribution solution that brings the full power of mobile ad measureme s.homepage = 'https://github.com/adjust/ios_adobe_extension' s.license = { :type => 'MIT', :file => 'LICENSE' } s.author = { 'Adjust SDK Team' => 'sdk@adjust.com' } - s.source = { :git => 'https://github.com/adjust/ios_adobe_extension.git', :tag => "v1.0.4" } + s.source = { :git => 'https://github.com/adjust/ios_adobe_extension.git', :tag => "v1.1.0" } s.ios.deployment_target = '10.0' diff --git a/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m b/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m index 91135a2..625f9c9 100644 --- a/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m +++ b/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m @@ -12,7 +12,7 @@ NSString * const ADJAdobeExtensionLogTag = @"AdjustAdobeExtension"; NSString * const ADJAdobeExtensionName = @"com.adjust.adobeextension"; -NSString * const ADJAdobeExtensionSdkPrefix = @"adobe_ext1.0.4"; +NSString * const ADJAdobeExtensionSdkPrefix = @"adobe_ext1.1.0"; NSString * const ADJAdobeEventDataKeyAction = @"action"; NSString * const ADJAdobeEventDataKeyContextData = @"contextdata"; From eb490d51459dd9b07a373d9911f3d9154bab0517 Mon Sep 17 00:00:00 2001 From: Genady Buchatsky Date: Fri, 8 Jul 2022 12:45:32 +0200 Subject: [PATCH 07/17] docs: updated CHANGELOG --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72eb28f..dc1ce9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +### Version 1.1.0 (8th July 2022) +#### Added + - Added ability to send event callback and partner parameters. + - Added ability to send push token. + ### Version 1.0.4 (9th May 2022) #### Added - Added Swift Package Manager support. From d9365589a5019f7311ee9295b9bb8af50800e33b Mon Sep 17 00:00:00 2001 From: uerceg Date: Tue, 19 Jul 2022 10:06:21 +0200 Subject: [PATCH 08/17] build: update s.author podspec field --- AdjustAdobeExtension.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AdjustAdobeExtension.podspec b/AdjustAdobeExtension.podspec index 6004f54..4292f56 100644 --- a/AdjustAdobeExtension.podspec +++ b/AdjustAdobeExtension.podspec @@ -8,7 +8,7 @@ A leading attribution solution that brings the full power of mobile ad measureme DESC s.homepage = 'https://github.com/adjust/ios_adobe_extension' s.license = { :type => 'MIT', :file => 'LICENSE' } - s.author = { 'Adjust SDK Team' => 'sdk@adjust.com' } + s.author = { 'Adjust' => 'sdk@adjust.com' } s.source = { :git => 'https://github.com/adjust/ios_adobe_extension.git', :tag => "v1.1.0" } s.ios.deployment_target = '10.0' From ade709ca8aacd91181a6d4260eadd2540ce31124 Mon Sep 17 00:00:00 2001 From: uerceg Date: Tue, 19 Jul 2022 10:06:42 +0200 Subject: [PATCH 09/17] build: update native iOS SDK dependency to v4.31.0 --- AdjustAdobeExtension.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AdjustAdobeExtension.podspec b/AdjustAdobeExtension.podspec index 4292f56..96b1c66 100644 --- a/AdjustAdobeExtension.podspec +++ b/AdjustAdobeExtension.podspec @@ -19,6 +19,6 @@ A leading attribution solution that brings the full power of mobile ad measureme s.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64'} s.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64'} - s.dependency 'Adjust', '4.30.0' + s.dependency 'Adjust', '4.31.0' s.dependency 'ACPCore' end From 122721c776ac194e0be814e57f78819c74f358b0 Mon Sep 17 00:00:00 2001 From: uerceg Date: Tue, 19 Jul 2022 12:41:57 +0200 Subject: [PATCH 10/17] style: clean up a few things --- AdjustAdobeExtension/Classes/AdjustAdobeExtension.h | 6 +++--- AdjustAdobeExtension/Classes/AdjustAdobeExtension.m | 11 +++-------- .../Classes/AdjustAdobeExtensionConfig.h | 1 - 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/AdjustAdobeExtension/Classes/AdjustAdobeExtension.h b/AdjustAdobeExtension/Classes/AdjustAdobeExtension.h index 5acdae0..31a2c95 100644 --- a/AdjustAdobeExtension/Classes/AdjustAdobeExtension.h +++ b/AdjustAdobeExtension/Classes/AdjustAdobeExtension.h @@ -23,20 +23,20 @@ NS_ASSUME_NONNULL_BEGIN extern NSString * const ADJAdobeExtensionLogTag; extern NSString * const ADJAdobeExtensionSdkPrefix; +// Action types extern NSString * const ADJAdobeAdjustActionTrackEvent; extern NSString * const ADJAdobeAdjustActionSetPushToken; +// Adjust Event extern NSString * const ADJAdobeAdjustEventToken; extern NSString * const ADJAdobeAdjustEventCurrency; extern NSString * const ADJAdobeAdjustEventRevenue; extern NSString * const ADJAdobeAdjustEventCallbackParamPrefix; extern NSString * const ADJAdobeAdjustEventPartnerParamPrefix; +// Push token extern NSString * const ADJAdobeAdjustPushToken; - - - @interface AdjustAdobeExtension : ACPExtension + (void)registerExtensionWithConfig:(AdjustAdobeExtensionConfig *)config; diff --git a/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m b/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m index 625f9c9..a0c2079 100644 --- a/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m +++ b/AdjustAdobeExtension/Classes/AdjustAdobeExtension.m @@ -38,16 +38,15 @@ @interface AdjustAdobeExtension() @property (nonatomic, assign) BOOL sdkInitialized; @property (nonatomic, strong) NSMutableArray *receivedEvents; @property (nonatomic, strong) dispatch_queue_t syncQueue; -@property (nonatomic,strong) NSNumber *numNan; -@property (nonatomic,strong) NSNumber *numPlusInf; -@property (nonatomic,strong) NSNumber *numMinusInf; +@property (nonatomic,strong) NSNumber *numNan; +@property (nonatomic,strong) NSNumber *numPlusInf; +@property (nonatomic,strong) NSNumber *numMinusInf; @end @implementation AdjustAdobeExtension + (void)registerExtensionWithConfig:(AdjustAdobeExtensionConfig *)config { - if (config == nil) { [ACPCore log:ACPMobileLogLevelError tag:ADJAdobeExtensionLogTag @@ -136,9 +135,7 @@ - (instancetype)init { } - (void)setupAdjustWithAppToken:(NSString *)appToken trackAttribution:(BOOL)trackAttribution { - dispatch_async(self.syncQueue, ^{ - if (!_configInstance) { [ACPCore log:ACPMobileLogLevelError tag:ADJAdobeExtensionLogTag @@ -193,7 +190,6 @@ - (void)handleEventData:(nullable NSDictionary *)eventData { } - (void)processEvent:(nullable NSDictionary *)eventData { - if (eventData == nil) { [ACPCore log:ACPMobileLogLevelError tag:ADJAdobeExtensionLogTag @@ -230,7 +226,6 @@ - (void)setPushToken:(NSDictionary *)contextData { } - (void)trackEvent:(NSDictionary *)contextData { - NSString *adjEventToken = contextData[ADJAdobeAdjustEventToken]; if (adjEventToken == nil) { return; diff --git a/AdjustAdobeExtension/Classes/AdjustAdobeExtensionConfig.h b/AdjustAdobeExtension/Classes/AdjustAdobeExtensionConfig.h index 9d35762..5dd648c 100644 --- a/AdjustAdobeExtension/Classes/AdjustAdobeExtensionConfig.h +++ b/AdjustAdobeExtension/Classes/AdjustAdobeExtensionConfig.h @@ -13,7 +13,6 @@ #import #endif - typedef void (^CallbackAttributionChangedBlock)(ADJAttribution * _Nullable attribution); typedef BOOL (^CallbackDeeplinkResponseBlock)(NSURL * _Nullable deeplink); From c717e38554e6af06410d91392a70f5a1b4501c6a Mon Sep 17 00:00:00 2001 From: uerceg Date: Tue, 19 Jul 2022 13:41:26 +0200 Subject: [PATCH 11/17] docs: update VERSION file to 1.1.0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index ee90284..9084fa2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.4 +1.1.0 From 12b7c8a98ffe95880dcc65c538a7267f21b20679 Mon Sep 17 00:00:00 2001 From: uerceg Date: Tue, 19 Jul 2022 13:42:41 +0200 Subject: [PATCH 12/17] docs: update CHANGELOG --- CHANGELOG.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc1ce9b..20ad64d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,12 @@ -### Version 1.1.0 (8th July 2022) +### Version 1.1.0 (20th July 2022) #### Added - - Added ability to send event callback and partner parameters. - - Added ability to send push token. +- Added ability to send event callback and partner parameters. +- Added ability to send push token. + +#### Native iOS SDK +- [iOS@v4.31.0](https://github.com/adjust/ios_sdk/tree/v4.31.0) + +--- ### Version 1.0.4 (9th May 2022) #### Added From f84011ae74adf02baaa56c29d7cad141086fe152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uglje=C5=A1a=20Erceg?= Date: Wed, 20 Jul 2022 23:10:18 +0200 Subject: [PATCH 13/17] docs: update README --- README.md | 89 ++++++++++++++++++------------------------------------- 1 file changed, 29 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index 6ad2be0..aa5e2c3 100644 --- a/README.md +++ b/README.md @@ -9,21 +9,16 @@ This is the iOS Adobe Mobile Extension of Adjust™. You can read more about Adj * [Add the Adjust Extension to your project](#iae-sdk-add) * [Cocoapods integration](#iae-sdk-add-cocoapods) * [Swift Package Manager integration](#iae-sdk-add-spm) + * [Add iOS frameworks](#iae-sdk-frameworks) * [Integrate the Adjust Extension into your app](#iae-sdk-integrate) * [Basic setup](#iae-basic-setup) - * [Session tracking](#iae-session-tracking) * [Attribution](#iae-attribution) - * [Add iOS frameworks](#iae-sdk-frameworks) ### [Events tracking](#iae-tracking) * [Track event](#iae-track-event) * [Track revenue](#iae-track-event-revenue) - -### [Custom parameters](#iae-custom-parameters) - * [Custom parameters overview](#iae-custom-parameters-overview) - * [Event parameters](#iae-event-parameters) - * [Event callback parameters](#iae-event-callback-parameters) - * [Event partner parameters](#iae-event-partner-parameters) + * [Callback parameters](#iae-event-callback-parameters) + * [Partner parameters](#iae-event-partner-parameters) ### [Additional features](#iae-additional-features) * [Attribution callback](#iae-attribution-callback) @@ -34,7 +29,7 @@ This is the iOS Adobe Mobile Extension of Adjust™. You can read more about Adj ### Example app -There is an example app inside the [Example][example-app] directory. +There is an example app inside the [Example](Example/) directory. Please run `pod install` in this folder to build the example application dependencies and then open `AdjustAdobeExtension.xcworkspace` to test the example application. ## Add the Adjust Extension to your project @@ -60,6 +55,16 @@ Due to a missing SPM support in Adobe ACP SDKs, all required Adobe frameworks ar In the `Frameworks, Libraries, and Embedded Content` section of your App target's `General` tab, add the following frameworks and libraries required for Adobe frameworks: `UIKit`, `SystemConfiguration`, `WebKit`, `UserNotifications`, `libsqlite3.0`, `libc++`, `libz`. +## Add iOS frameworks + +Adjust SDK is able to get additional information in case you link additional iOS frameworks to your app. Please, add following frameworks in case you want to enable Adjust SDK features based on their presence in your app and mark them as optional: + +- `AdSupport.framework` - This framework is needed so that SDK can access to IDFA value and (prior to iOS 14) LAT information. +- `iAd.framework` - This framework is needed so that SDK can automatically handle attribution for ASA campaigns you might be running. +- `AdServices.framework` - For devices running iOS 14.3 or higher, this framework allows the SDK to automatically handle attribution for ASA campaigns. It is required when leveraging the Apple Ads Attribution API. +- `StoreKit.framework` - This framework is needed for access to `SKAdNetwork` framework and for Adjust SDK to handle communication with it automatically in iOS 14 or later. +- `AppTrackingTransparency.framework` - This framework is needed in iOS 14 and later for SDK to be able to wrap user's tracking consent dialog and access to value of the user's consent to be tracked or not. + ## Integrate the Adjust Extension into your app Add the following import statement: @@ -81,7 +86,6 @@ You don't need to start the Adjust Extension manually. First, set the configurat ```objc // Objective-C - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [ACPCore setLogLevel:ACPMobileLogLevelVerbose]; [ACPCore configureWithAppId:@"{your_adobe_app_id}"]; @@ -98,7 +102,6 @@ You don't need to start the Adjust Extension manually. First, set the configurat ```swift // Swift func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - ACPCore.setLogLevel(ACPMobileLogLevel.verbose) ACPCore.configure(withAppId: "{your_adobe_app_id}") @@ -126,10 +129,6 @@ ADJEnvironmentProduction We use this environment to distinguish between real traffic and test traffic from test devices. Keeping the environment updated according to your current status is very important! -## Session tracking - -Adjust SDK can track sessions in your app based on Activity lifecycle. - ## Attribution The option to share attribution data with Adobe is in the Launch dashboard under the extensions configuration and is on by default. Adjust tracks the action name `Adjust Campaign Data Received` with the following attribution information from Adjust: @@ -139,21 +138,11 @@ The option to share attribution data with Adobe is in the Launch dashboard under * `Adjust AdGroup` * `Adjust Creative` -## Add iOS frameworks - -Adjust SDK is able to get additional information in case you link additional iOS frameworks to your app. Please, add following frameworks in case you want to enable Adjust SDK features based on their presence in your app and mark them as optional: - -- `AdSupport.framework` - This framework is needed so that SDK can access to IDFA value and (prior to iOS 14) LAT information. -- `iAd.framework` - This framework is needed so that SDK can automatically handle attribution for ASA campaigns you might be running. -- `AdServices.framework` - For devices running iOS 14.3 or higher, this framework allows the SDK to automatically handle attribution for ASA campaigns. It is required when leveraging the Apple Ads Attribution API. -- `StoreKit.framework` - This framework is needed for access to `SKAdNetwork` framework and for Adjust SDK to handle communication with it automatically in iOS 14 or later. -- `AppTrackingTransparency.framework` - This framework is needed in iOS 14 and later for SDK to be able to wrap user's tracking consent dialog and access to value of the user's consent to be tracked or not. - ## Events tracking ### Track event -You can use Adobe `[ACPCore trackAction:]` API for [`event tracking`][event-tracking]. Suppose you want to track every tap on a button. To do so, you'll create a new event token in your [dashboard]. Let's say that the event token is `abc123`. In your button's press handling method, add the following lines to track the click: +You can use Adobe `[ACPCore trackAction:]` API for [`event tracking`](https://docs.adjust.com/en/event-tracking). Suppose you want to track every tap on a button. To do so, you'll create a new event token in your [dashboard](https://dash.adjust.com/). Let's say that the event token is `abc123`. In your button's press handling method, add the following lines to track the click: ```objc // Objective-C @@ -191,22 +180,11 @@ dataDict[ADJAdobeAdjustEventCurrency] = "EUR" ACPCore.trackAction(ADJAdobeAdjustActionTrackEvent, data: dataDict) ``` -## Custom parameters +### Callback parameters -### Custom parameters overview +You can register a callback URL for your events in your [dashboard](https://dash.adjust.com/). We will send a GET request to that URL whenever the event is tracked. You can add callback parameters to that event by adding them as key value pair to the context data map before tracking it. We will then append these parameters to your callback URL. -In addition to the data points the Adjust SDK collects by default, you can use the extension to track and add as many custom values as you need (user IDs, product IDs, etc.) to the event or session. Custom parameters are only available as raw data and will **not** appear in your Adjust dashboard. - -You should use **callback parameters** for the values you collect for your own internal use, and **partner parameters** for those you share with external partners. If a value (e.g. product ID) is tracked both for internal use and external partner use, we recommend you track it with both callback and partner parameters. - - -### Event parameters - -### Event callback parameters - -You can register a callback URL for your events in your [dashboard]. We will send a GET request to that URL whenever the event is tracked. You can add callback parameters to that event by adding them as key value pair to the context data map before tracking it. We will then append these parameters to your callback URL. - -For example, if you've registered the URL `http://www.example.com/callback`, then you would track an event like this: +For example, suppose you have registered the URL `https://www.mydomain.com/callback` then track an event like this: ```objc // Objective-C @@ -226,23 +204,21 @@ dataDict[ADJAdobeAdjustEventCallbackParamPrefix.appending("key2")] = "value2" ACPCore.trackAction(ADJAdobeAdjustActionTrackEvent, data: dataDict) ``` - -In this case we would track the event and send a request to: +In that case we would track the event and send a request to: ``` -http://www.example.com/callback?key1=value1&key2=value2 +http://www.mydomain.com/callback?key=value&foo=bar ``` -Adjust supports a variety of placeholders, which can be used as parameter values. In the resulting callback, we would replace the placeholder with an appropriate value. Please note that we don't store any of your custom parameters. We **only** append them to your callbacks. If you haven't registered a callback for an event, we will not even read these parameters. +It should be mentioned that we support a variety of placeholders like `{idfa}` that can be used as parameter values. In the resulting callback this placeholder would be replaced with the ID for Advertisers of the current device. Also note that we don't store any of your custom parameters, but only append them to your callbacks, thus without a callback they will not be saved nor sent to you. -You can read more about URL callbacks (including a full list of available values) in our [callbacks guide][callbacks-guide]. +You can read more about using URL callbacks, including a full list of available values, in our [callbacks guide](https://docs.adjust.com/en/callbacks). -### Event partner parameters +### Partner parameters -When your parameters are activated in the Adjust dashboard, you have the option to transmit them to your network partners. - -This works similarly to the callback parameters mentioned above; +You can also add parameters to be transmitted to network partners, which have been activated in your Adjust dashboard. +You can add partner parameters to that event by adding them as key value pair to the context data map before tracking it. ```objc // Objective-C @@ -262,7 +238,7 @@ dataDict[ADJAdobeAdjustEventPartnerParamPrefix.appending("key2")] = "value2" ACPCore.trackAction(ADJAdobeAdjustActionTrackEvent, data: dataDict) ``` -You can read more about special partners and these integrations in our [guide to special partners][special-partners]. +You can read more about special partners and these integrations in our [guide to special partners](https://docs.adjust.com/en/special-partners). ## Additional features @@ -272,7 +248,7 @@ Once you have integrated the Adjust Extension for Adobe Experience SDK into your You can register a callback code block to be notified of tracker attribution changes. Due to the different sources we consider for attribution, we cannot provide this information synchronously. -Please see our [attribution data policies][attribution-data] for more information. +Please see our [attribution data policies](https://github.com/adjust/sdks/blob/master/doc/attribution-data.md) for more information. With the extension config instance, add the attribution callback before you start the SDK: @@ -330,13 +306,13 @@ if let config = AdjustAdobeExtensionConfig.init(environment: ADJEnvironmentSandb } ``` -After the Adjust SDK receives the deep link information from our backend, the SDK will deliver you its content via the callback block and expect the boolean return value from you. This return value represents your decision on whether or not the Adjust SDK should launch the activity to which you have assigned the scheme name from the deeplink. +After the Adjust SDK receives the deep link information from our backend, the SDK will deliver you its content via the callback block and expect the boolean return value from you. This return value represents your decision on whether or not the Adjust SDK should open the deep link or not. ### Push token (uninstall tracking) Push tokens are used for Audience Builder and client callbacks; they are also required for uninstall and reinstall tracking. -To send us the push notification token, add the following call to Adjust once you have obtained your token (or whenever its value changes): +To send us the APNs push notification token, add the following call to Adjust once you have obtained your token (or whenever its value changes): ```objc // Objective-C @@ -351,10 +327,3 @@ var dataDict: Dictionary = [String : String]() dataDict[ADJAdobeAdjustPushToken] = "your_app_push_token" ACPCore.trackAction(ADJAdobeAdjustActionSetPushToken, data: dataDict) ``` - -[example-app]: Example/ -[event-tracking]: https://docs.adjust.com/en/event-tracking -[dashboard]: http://dash.adjust.com/ -[callbacks-guide]: https://docs.adjust.com/en/callbacks -[special-partners]: https://docs.adjust.com/en/special-partners -[attribution-data]: https://github.com/adjust/sdks/blob/master/doc/attribution-data.md From 535051ce318544f5e04044b416e91b2a197111a5 Mon Sep 17 00:00:00 2001 From: uerceg Date: Wed, 20 Jul 2022 23:11:08 +0200 Subject: [PATCH 14/17] docs: update CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20ad64d..a9d891e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### Version 1.1.0 (20th July 2022) +### Version 1.1.0 (21st July 2022) #### Added - Added ability to send event callback and partner parameters. - Added ability to send push token. From 4ca5905cd33b01bf68d867e13e884e7c6a1822cf Mon Sep 17 00:00:00 2001 From: Genady Buchatsky Date: Thu, 21 Jul 2022 12:52:31 +0200 Subject: [PATCH 15/17] build: update SPM papckage dependency to v4.31.0 --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index e6fa737..2493351 100644 --- a/Package.swift +++ b/Package.swift @@ -15,7 +15,7 @@ let package = Package( .package( name: "Adjust", url: "https://github.com/adjust/ios_sdk.git", - from: "4.30.0" + from: "4.31.0" ), ], targets: [ From fc01083473d3c0071e3df6bd0d1f9b1969bc8c77 Mon Sep 17 00:00:00 2001 From: Genady Buchatsky Date: Thu, 21 Jul 2022 13:49:31 +0200 Subject: [PATCH 16/17] build: updates Adobe SDKs paths to a new release page --- Package.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Package.swift b/Package.swift index 2493351..830df5f 100644 --- a/Package.swift +++ b/Package.swift @@ -29,22 +29,22 @@ let package = Package( ), .binaryTarget( name: "ACPCore", - url: "https://github.com/adjust/ios_adobe_extension/releases/download/v1.0.4/ACPCore.xcframework-2.9.5.zip", + url: "https://github.com/adjust/ios_adobe_extension/releases/download/v1.1.0/ACPCore.xcframework-2.9.5.zip", checksum: "1feb78e211bfc1d4e52e499323772f66c3eaab56434342465f7ee8a036a51fa9" ), .binaryTarget( name: "ACPIdentity", - url: "https://github.com/adjust/ios_adobe_extension/releases/download/v1.0.4/ACPIdentity.xcframework-2.5.2.zip", + url: "https://github.com/adjust/ios_adobe_extension/releases/download/v1.1.0/ACPIdentity.xcframework-2.5.2.zip", checksum: "9a4843568ad0832e575dbecb2524265bbfd9baf2557bc972f78b4359d70f8bc0" ), .binaryTarget( name: "ACPLifecycle", - url: "https://github.com/adjust/ios_adobe_extension/releases/download/v1.0.4/ACPLifecycle.xcframework-2.2.1.zip", + url: "https://github.com/adjust/ios_adobe_extension/releases/download/v1.1.0/ACPLifecycle.xcframework-2.2.1.zip", checksum: "02d7b6a1c615d9f5b222d58a95a0ded1ce4b1dac60fbecc9858d9e8dcd74c2eb" ), .binaryTarget( name: "ACPSignal", - url: "https://github.com/adjust/ios_adobe_extension/releases/download/v1.0.4/ACPSignal.xcframework-2.2.0.zip", + url: "https://github.com/adjust/ios_adobe_extension/releases/download/v1.1.0/ACPSignal.xcframework-2.2.0.zip", checksum: "2f7c9db8e8163fe2c5aa3e89fce485075b32751e65402f10a69eea674dd965a5" ) ] From 043a167bd50098aba4e9003bc3d4b408474b76a7 Mon Sep 17 00:00:00 2001 From: Genady Buchatsky Date: Thu, 21 Jul 2022 14:04:12 +0200 Subject: [PATCH 17/17] build: updates Podfile.lock --- Example/Podfile.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Example/Podfile.lock b/Example/Podfile.lock index 65f9a43..20c580a 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -12,12 +12,12 @@ PODS: - ACPUserProfile/xcframeworks (= 2.2.0) - ACPUserProfile/xcframeworks (2.2.0): - ACPCore (>= 2.9.0) - - Adjust (4.30.0): - - Adjust/Core (= 4.30.0) - - Adjust/Core (4.30.0) - - AdjustAdobeExtension (1.0.4): + - Adjust (4.31.0): + - Adjust/Core (= 4.31.0) + - Adjust/Core (4.31.0) + - AdjustAdobeExtension (1.1.0): - ACPCore - - Adjust (= 4.30.0) + - Adjust (= 4.31.0) DEPENDENCIES: - ACPCore (~> 2.0) @@ -40,8 +40,8 @@ SPEC CHECKSUMS: ACPCore: f6c5ec32fe162e61a18bec2ae79c8c5a48362a46 ACPGriffon: 5b46aa44e9667b1ff5d35aa37a84992b58d2aadf ACPUserProfile: 34bd51d00a2ae1add3d04eab0a313b73cb01b904 - Adjust: 6ed5493e91e9a77f6515d94f640bb72506a06b9d - AdjustAdobeExtension: 809dd9ddd0d8c65f1e0370b15dd21b45c9c708be + Adjust: 8d4c9da5bb1d161db5d35dd091e34a641c9511ef + AdjustAdobeExtension: 166465857cb0c62d34563d91bfd702e762eac6f1 PODFILE CHECKSUM: 9d0e231ac981dcf17cb67e756778f0a8f6f6332c