This is a step-by-step guide to help you integrate and configure the Adjust Extension in your Adobe Experience app for iOS. With this extension, you can seamlessly integrate Adjust with the Adobe Experience SDK to capture and send attribution data and in-app event information.
This extension enables you to send installs, sessions, custom in-app events, and other types of data to Adjust. Follow this guide to set up and configure the Adjust Extension and verify that you can send install information to Adjust.
Set up your project 
Follow these steps to set up your project to support the Adjust Extension for Adobe Experience SDK.
Install the Adjust Extension 
To use the Adjust Extension for Adobe Experience SDK, you need to add it to your project as a dependency.
If you’re using Swift Package Manager, enter the following URL:
https://github.com/adjust/ios_adobe_extension.git 
 
If you’re using CocoaPods, add the following line to your Podfile:
pod  'AdjustAdobeExtension' 
 
Add iOS frameworks 
The Adjust Extension requires additional iOS frameworks to access information about a device. Add the following frameworks and mark them as optional  to enable these features.
AdSupport.framework 
Used to access the ID for Advertisers (IDFA) and Limited Ad Tracking (LAT) information. LAT is available only on devices running iOS 14 or earlier.
 
AppTrackingTransparency.framework 
Used to enable the Adjust Extension to wrap the user AppTrackingTransparency (ATT) consent dialog and access a user’s ATT consent data. ATT is avaliable only on devices running iOS 14 or later.
 
AdServices.framework 
Used to enable the Adjust Extension to automatically handle attribution for Apple Search Ads (ASA) campaigns on devices running iOS 14.3 or later. Required when using the Apple Ads Attribution API.
 
StoreKit.framework 
Used to enable the Adjust Extension to communicate with the SKAdNetwork framework on devices running iOS 14 or later.
 
  
Integration guide 
Once you’ve completed the project setup steps, you can integrate the Adjust SDK. The following guide shows you how to:
Add the Adjust Extension to your Adobe Experience app. 
Set your logging level to verbose  to retrieve as much detail as possible from the extension. 
Test the Extension in sandbox  mode to ensure it sends data to Adjust. 
Enable your app to open deep links. 
Register with the Adobe Experience SDK. 
 
To do this, you need to create the following files:
   
AppDelegate.swift: this is where you’ll configure the Adjust Extension. 
ViewController.swift: this is where you’ll create functions using the Adjust Extension. 
     
AppDelegate.m: the method file for your app delegate. This is where you’ll configure the Adjust Extension. 
AppDelegate.h: the header file for your app delegate. 
ViewController.m: the method file for your view controller. This is where you’ll create functions using the Adjust Extension. 
ViewController.h: the header file for your view controller. 
 For the purposes of this guide, use the following header files:
@interface   AppDelegate  :  UIResponder  <UIApplicationDelegate> 
@interface   ViewController  :  UIViewController 
         
Import classes 
First, you need to import some classes into your application files. Import the following classes into your App Delegate:
AEPCore 
Contains the implementation of the Event Hub.
 
AEPServices 
Provides implementations for platform support such as networking, disk access, and database management.
 
AdjustAdobeExtension 
The Adjust Extension for Adobe Experience SDK.
 
  
   import   AdjustAdobeExtension 
     #import   <AdjustAdobeExtension/AdjustAdobeExtension.h> 
         
Next, import the following classes into your View Controller:
AEPCore 
Contains the implementation of the Event Hub.
 
AdjustAdobeExtension 
The Adjust Extension for Adobe Experience SDK.
 
  
   import   AdjustAdobeExtension 
     #import   "ViewController.h" 
#import   <AdjustAdobeExtension/AdjustAdobeExtension.h> 
         
Create an App Delegate 
To register the Adjust iOS Extension for Adobe Experience SDK, you need to create an App Delegate. If you’ve not yet created an App Delegate, follow these steps:
Create a new AppDelegate implementation. 
 
   import   AdjustAdobeExtension 
class   AppDelegate :  UIResponder ,  UIApplicationDelegate  {} 
     #import   <AdjustAdobeExtension/AdjustAdobeExtension.h> 
@implementation   AppDelegate 
         
Within your AppDelegate implementation, create a new function called application that returns a boolean. This function takes the following arguments: 
 
application: UIApplication 
The singleton app object.
 
launchOptions: [UIApplication.LaunchOptionsKey : Any] 
A dictionary indicating the reason the app was launched.
 
  
   class   AppDelegate :  UIResponder ,  UIApplicationDelegate  { 
    func   application ( _  application: UIApplication,  didFinishLaunchingWithOptions  launchOptions: [UIApplication.LaunchOptionsKey:  Any ] ? )  ->   Bool  {} 
     @implementation   AppDelegate 
- ( BOOL ) application: (UIApplication  * )application  didFinishLaunchingWithOptions: ( NSDictionary   * )launchOptions {} 
         
Once you’ve created the App Delegate, follow these steps to configure the Adjust iOS Extension for Adobe Experience SDK:
Inside your application function, set your logging level by calling the setLogLevel method of the AEPMobileCore class with the following argument: 
 
logLevel 
The level of logging you want to enable.
 
 
Trace: enable all logging. 
Debug: disable verbose logging. 
Warning: log only errors and warnings. 
Error: log only errors. 
  
   func   application ( _  application: UIApplication,  didFinishLaunchingWithOptions  launchOptions: [UIApplication.LaunchOptionsKey:  Any ] ? )  ->   Bool  { 
    MobileCore. setLogLevel (LogLevel.trace) 
     -  ( BOOL )application:(UIApplication  * )application didFinishLaunchingWithOptions:( NSDictionary   * )launchOptions { 
    [AEPMobileCore  setLogLevel:  AEPLogLevelTrace]; 
         
Create a new UIApplicationState variable called appState. You’ll use this to communicate the app state with the Adobe Experience SDK. 
 
   func   application ( _  application: UIApplication,  didFinishLaunchingWithOptions  launchOptions: [UIApplication.LaunchOptionsKey:  Any ] ? )  ->   Bool  { 
    MobileCore. setLogLevel (LogLevel.trace) 
    let  appState  =  application.applicationState 
     -  ( BOOL )application:(UIApplication  * )application didFinishLaunchingWithOptions:( NSDictionary   * )launchOptions { 
    [AEPMobileCore  setLogLevel:  AEPLogLevelTrace]; 
    const  UIApplicationState appState  =  application.applicationState; 
         
Create a new AdjustAdobeExtensionConfig instance named config with the following argument: 
 
environment: NSString 
The environment in which your device is running.
 
 
Pass ADJEnvironmentSandbox when testing. 
Pass ADJEnvironmentProduction when running the app in production. 
  
   func   application ( _  application: UIApplication,  didFinishLaunchingWithOptions  launchOptions: [UIApplication.LaunchOptionsKey:  Any ] ? )  ->   Bool  { 
    MobileCore. setLogLevel (LogLevel.trace) 
    let  appState  =  application.applicationState 
    if   let  config  =   AdjustAdobeExtensionConfig ( environment : ADJEnvironmentSandbox) {} 
     -  ( BOOL )application:(UIApplication  * )application didFinishLaunchingWithOptions:( NSDictionary   * )launchOptions { 
    [AEPMobileCore  setLogLevel:  AEPLogLevelTrace]; 
    const  UIApplicationState appState  =  application.applicationState; 
    AdjustAdobeExtensionConfig  * config  =  [AdjustAdobeExtensionConfig  configWithEnvironment: ADJEnvironmentSandbox]; 
         
Call the setConfiguration method of the AdjustAdobeExtension class with your configuration instance as an argument to register the configuration. 
 
   func   application ( _  application: UIApplication,  didFinishLaunchingWithOptions  launchOptions: [UIApplication.LaunchOptionsKey:  Any ] ? )  ->   Bool  { 
    MobileCore. setLogLevel (LogLevel.trace) 
    let  appState  =  application.applicationState 
    if   let  config  =   AdjustAdobeExtensionConfig ( environment : ADJEnvironmentSandbox) { 
       AdjustAdobeExtension. setConfiguration (config) 
     -  ( BOOL )application:(UIApplication  * )application didFinishLaunchingWithOptions:( NSDictionary   * )launchOptions { 
    [AEPMobileCore  setLogLevel:  AEPLogLevelTrace]; 
    const  UIApplicationState appState  =  application.applicationState; 
    AdjustAdobeExtensionConfig  * config  =  [AdjustAdobeExtensionConfig  configWithEnvironment: ADJEnvironmentSandbox]; 
    [AdjustAdobeExtension  setConfiguration: config]; 
         
Register the Adjust Extension 
Once you’ve configured the Adjust Extension, you need to register it with the Adobe Experience SDK. To do this:
Inside your application function, call the registerExtensions method of the AEPMobileCore class with the following arguments: 
 
extensions: NSArray<Class*>* _Nonnull 
A list of extensions.
 
completion: (^ _Nullable)(void)) 
A completion handler.
 
  
For the purposes of this guide, pass the AdjustAdobeExtension class for extensions. You’ll set your completion handler in the next step.
   func   application ( _  application: UIApplication,  didFinishLaunchingWithOptions  launchOptions: [UIApplication.LaunchOptionsKey:  Any ] ? )  ->   Bool  { 
    MobileCore. setLogLevel (LogLevel.trace) 
    let  appState  =  application.applicationState 
    if   let  config  =   AdjustAdobeExtensionConfig ( environment : ADJEnvironmentSandbox) { 
       AdjustAdobeExtension. setConfiguration (config) 
    MobileCore. registerExtensions ([AdjustAdobeExtension. self ]) {} 
     -  ( BOOL )application:(UIApplication  * )application didFinishLaunchingWithOptions:( NSDictionary   * )launchOptions { 
    [AEPMobileCore  setLogLevel:  AEPLogLevelTrace]; 
    const  UIApplicationState appState  =  application.applicationState; 
    AdjustAdobeExtensionConfig  * config  =  [AdjustAdobeExtensionConfig  configWithEnvironment: ADJEnvironmentSandbox]; 
    [AdjustAdobeExtension  setConfiguration: config]; 
    [AEPMobileCore  registerExtensions: @[AdjustAdobeExtension.class] 
         
Within the completion handler, call the configureWithAppId method of the AEPMobileCore class with your Adobe App ID. 
 
   func   application ( _  application: UIApplication,  didFinishLaunchingWithOptions  launchOptions: [UIApplication.LaunchOptionsKey:  Any ] ? )  ->   Bool  { 
    MobileCore. setLogLevel (LogLevel.trace) 
    let  appState  =  application.applicationState 
    if   let  config  =   AdjustAdobeExtensionConfig ( environment : ADJEnvironmentSandbox) { 
       AdjustAdobeExtension. setConfiguration (config) 
    MobileCore. registerExtensions ([AdjustAdobeExtension. self ]) { 
       MobileCore. configureWith ( appId :  "{your_adobe_app_id}" ) 
     -  ( BOOL )application:(UIApplication  * )application didFinishLaunchingWithOptions:( NSDictionary   * )launchOptions { 
    [AEPMobileCore  setLogLevel:  AEPLogLevelTrace]; 
    const  UIApplicationState appState  =  application.applicationState; 
    AdjustAdobeExtensionConfig  * config  =  [AdjustAdobeExtensionConfig  configWithEnvironment: ADJEnvironmentSandbox]; 
    [AdjustAdobeExtension  setConfiguration: config]; 
    [AEPMobileCore  registerExtensions: @[AdjustAdobeExtension.class] 
       [AEPMobileCore  configureWithAppId:   @"{your_adobe_app_id}" ]; 
         
Inside your completion handler, add an if block to call the lifecycleStart method of the AEPMobileCore if the app isn’t in the background. 
 
   func   application ( _  application: UIApplication,  didFinishLaunchingWithOptions  launchOptions: [UIApplication.LaunchOptionsKey:  Any ] ? )  ->   Bool  { 
    MobileCore. setLogLevel (LogLevel.trace) 
    let  appState  =  application.applicationState 
    if   let  config  =   AdjustAdobeExtensionConfig ( environment : ADJEnvironmentSandbox) { 
       AdjustAdobeExtension. setConfiguration (config) 
    MobileCore. registerExtensions ([AdjustAdobeExtension. self ]) { 
       MobileCore. configureWith ( appId :  "{your_adobe_app_id}" ) 
       if  appState  !=  .background { 
          MobileCore. lifecycleStart ( additionalContextData :  nil ) 
     -  ( BOOL )application:(UIApplication  * )application didFinishLaunchingWithOptions:( NSDictionary   * )launchOptions { 
    [AEPMobileCore  setLogLevel:  AEPLogLevelTrace]; 
    const  UIApplicationState appState  =  application.applicationState; 
    AdjustAdobeExtensionConfig  * config  =  [AdjustAdobeExtensionConfig  configWithEnvironment: ADJEnvironmentSandbox]; 
    [AdjustAdobeExtension  setConfiguration: config]; 
    [AEPMobileCore  registerExtensions: @[AdjustAdobeExtension.class] 
       [AEPMobileCore  configureWithAppId:   @"{your_adobe_app_id}" ]; 
       if  (appState  !=  UIApplicationStateBackground) { 
          [AEPMobileCore  lifecycleStart:nil ]; 
         
Finally, return a true value at the top level of your application function. 
 
   func   application ( _  application: UIApplication,  didFinishLaunchingWithOptions  launchOptions: [UIApplication.LaunchOptionsKey:  Any ] ? )  ->   Bool  { 
    MobileCore. setLogLevel (LogLevel.trace) 
    let  appState  =  application.applicationState 
    if   let  config  =   AdjustAdobeExtensionConfig ( environment : ADJEnvironmentSandbox) { 
       AdjustAdobeExtension. setConfiguration (config) 
    MobileCore. registerExtensions ([AdjustAdobeExtension. self ]) { 
       MobileCore. configureWith ( appId :  "{your_adobe_app_id}" ) 
       if  appState  !=  .background { 
          MobileCore. lifecycleStart ( additionalContextData :  nil ) 
     -  ( BOOL )application:(UIApplication  * )application didFinishLaunchingWithOptions:( NSDictionary   * )launchOptions { 
    [AEPMobileCore  setLogLevel:  AEPLogLevelTrace]; 
    const  UIApplicationState appState  =  application.applicationState; 
    AdjustAdobeExtensionConfig  * config  =  [AdjustAdobeExtensionConfig  configWithEnvironment: ADJEnvironmentSandbox]; 
    [AdjustAdobeExtension  setConfiguration: config]; 
    [AEPMobileCore  registerExtensions: @[AdjustAdobeExtension.class] 
       [AEPMobileCore  configureWithAppId:   @"{your_adobe_app_id}" ]; 
       if  (appState  !=  UIApplicationStateBackground) { 
          [AEPMobileCore  lifecycleStart:nil ]; 
         
Set up deep link handling 
To configure the Adjust iOS Extension for Adobe Experience SDK to open deep links, follow these steps:
Within your AppDelegate implementation, create a new boolean function called application to handle opening deep links. Thie function takes the following arguments: 
 
app: UIApplication 
The singleton app object.
 
url: NSURL 
The URL resource to open in the app.
 
options: [UIApplicationOpenURLOptionsKey : id] 
A dictionary of options for handling the URL, containing keys that specify options related to the URL.
 
  
   func   application ( _  app: UIApplication,  open  url: URL,  options : [UIApplication.OpenURLOptionsKey :  Any ]  =  [ : ])  ->   Bool  {} 
     -  ( BOOL )application:(UIApplication  * )app openURL:( NSURL   * )url options:( NSDictionary < UIApplicationOpenURLOptionsKey, id>   * )options {} 
         
Inside this function, call the processDeeplink method of the Adjust class to open the deep link and return a true value. 
 
   func   application ( _  app: UIApplication,  open  url: URL,  options : [UIApplication.OpenURLOptionsKey :  Any ]  =  [ : ])  ->   Bool  { 
    if   let  deeplink  =   ADJDeeplink ( deeplink : url) { 
       Adjust. processDeeplink (deeplink) 
     -  ( BOOL )application:(UIApplication  * )app openURL:( NSURL   * )url options:( NSDictionary < UIApplicationOpenURLOptionsKey, id>   * )options { 
    [Adjust  processDeeplink:  [[ADJDeeplink  alloc ]  initWithDeeplink: url]]; 
         
Next, create another boolean function called application to handle resuming user activity. This function takes the following arguments: 
 
application: UIApplication 
The singleton app object.
 
userActivity: NSUserActivity 
The user activity object that represents the activity to continue.
 
restorationHandler: void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable) 
A handler block to use for restoring the app’s state if needed.
 
  
   func   application ( _  application: UIApplication,  continue  userActivity: NSUserActivity,  restorationHandler :  @escaping  ([UIUserActivityRestoring] ? )  ->   Void )  ->   Bool  {} 
     -  ( BOOL )application:(UIApplication  * )application continueUserActivity:(NSUserActivity  * )userActivity restorationHandler:( void  ( ^ )( NSArray <id <UIUserActivityRestoring> >   *  _Nullable))restorationHandler {} 
         
Inside this function, add a check to see if the app was opened by a link and call processDeeplink if it is. 
 
   func   application ( _  application: UIApplication,  continue  userActivity: NSUserActivity,  restorationHandler :  @escaping  ([UIUserActivityRestoring] ? )  ->   Void )  ->   Bool  { 
    if  userActivity.activityType  ==  NSUserActivityTypeBrowsingWeb { 
       if   let  incomingUrl  =  userActivity.webpageUrl { 
          if   let  deeplink  =   ADJDeeplink ( deeplink : incomingUrl) { 
             Adjust. processDeeplink (deeplink) 
     -  ( BOOL )application:(UIApplication  * )application continueUserActivity:(NSUserActivity  * )userActivity restorationHandler:( void  ( ^ )( NSArray <id <UIUserActivityRestoring> >   *  _Nullable))restorationHandler { 
    if  ([[userActivity  activityType ]  isEqualToString: NSUserActivityTypeBrowsingWeb]) { 
      [Adjust  proceessDeeplink: [[ADJDeeplink  alloc ]  initWithDeeplink: [userActivity  webpageURL ]]]; 
         
If you use short branded links , you can alternatively use the Adjust.processAndResolveDeeplink method to resolve your shortened link and return it to a callback function.
   func   application ( _  application: UIApplication,  continue  userActivity: NSUserActivity,  restorationHandler :  @escaping  ([UIUserActivityRestoring] ? )  ->   Void )  ->   Bool  { 
    if  userActivity.activityType  ==  NSUserActivityTypeBrowsingWeb { 
       if   let  incomingUrl  =  userActivity.webpageUrl { 
          if   let  deeplink  =   ADJDeeplink ( deeplink : incomingUrl) { 
             Adjust. processAndResolveDeeplink (deeplink) { resolveDeeplink  in 
                print ( "[ \(resolveDeeplink) ]" ) 
     -  ( BOOL )application:(UIApplication  * )application continueUserActivity:(NSUserActivity  * )userActivity restorationHandler:( void  ( ^ )( NSArray <id <UIUserActivityRestoring> >   *  _Nullable))restorationHandler { 
    if  ([[userActivity  activityType ]  isEqualToString: NSUserActivityTypeBrowsingWeb]) { 
       ADJDeeplink  * deeplink  =  [[ADJDeeplink  alloc ]  initWithDeeplink: [userActivity  webpageURL ]]; 
       [Adjust  processAndResolveDeeplink: deeplink 
                withCompletionHandler: ^ ( NSString   *  _Nullable resolvedLink) { 
                   NSLog ( @"[ %@ ]" , resolvedLink); 
         
Set up your View Controller 
Next, you need to set up your View Controller. You’ll use this file to set up your Adjust features later. For the purposes of this guide, you’re only going to set up the viewDidLoad function to handle application startup.
Inside your View Controller file, createa a new ViewController class implementation. 
 
   class   ViewController :  UIViewController  {} 
     @implementation   ViewController 
         
Inside your ViewController class, create a void function that calls super.viewDidLoad to initialize your view. 
 
   class   ViewController :  UIViewController  { 
    override   func   viewDidLoad () { 
     @implementation   ViewController 
         
Once you’ve completed these steps, build and run your app. After you launch your app, you should see the message Install tracked in your Xcode logs.