{"id":21478229,"url":"https://github.com/appsflyersdk/segment-appsflyer-ios","last_synced_at":"2025-10-31T14:30:28.694Z","repository":{"id":8703761,"uuid":"58304680","full_name":"AppsFlyerSDK/segment-appsflyer-ios","owner":"AppsFlyerSDK","description":"The AppsFlyer iOS SDK integration with Segment","archived":false,"fork":false,"pushed_at":"2024-08-20T11:15:45.000Z","size":1345,"stargazers_count":23,"open_issues_count":2,"forks_count":59,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-02-09T19:09:54.853Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://segment.com/docs/integrations/appsflyer/","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AppsFlyerSDK.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-05-08T09:14:00.000Z","updated_at":"2024-08-20T11:14:02.000Z","dependencies_parsed_at":"2024-03-12T14:48:10.223Z","dependency_job_id":"11dcb996-1c36-4cb5-a238-df63a98171e2","html_url":"https://github.com/AppsFlyerSDK/segment-appsflyer-ios","commit_stats":{"total_commits":361,"total_committers":33,"mean_commits":10.93939393939394,"dds":0.7617728531855956,"last_synced_commit":"2f3a28c694b447c6f592c11caaf0851ca1870cb2"},"previous_names":[],"tags_count":91,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AppsFlyerSDK%2Fsegment-appsflyer-ios","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AppsFlyerSDK%2Fsegment-appsflyer-ios/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AppsFlyerSDK%2Fsegment-appsflyer-ios/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AppsFlyerSDK%2Fsegment-appsflyer-ios/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AppsFlyerSDK","download_url":"https://codeload.github.com/AppsFlyerSDK/segment-appsflyer-ios/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239201667,"owners_count":19599079,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-23T11:17:19.432Z","updated_at":"2025-10-31T14:30:28.593Z","avatar_url":"https://github.com/AppsFlyerSDK.png","language":"Objective-C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://massets.appsflyer.com/wp-content/uploads/2018/06/20092440/static-ziv_1TP.png\"  width=\"400\" \u003e \r\n\r\n# AppsFlyer integration for Segment.\r\n\r\n## This is a Segment wrapper for AppsFlyer SDK that is built with iOS SDK v6.15.1.\n\r\n[![Version](https://img.shields.io/badge/cocoapods-compatible-brightgreen?logo=cocoapods\u0026logoColor=green\u0026style=flat)](http://cocoapods.org/pods/segment-appsflyer-ios)\r\n[![Carthage compatible](https://img.shields.io/badge/Carthage-not_compatible-C20000.svg?style=flat)](https://github.com/Carthage/Carthage)\r\n[![CI - Tests](https://github.com/AppsFlyerSDK/segment-appsflyer-ios/actions/workflows/unit-tests-workflow.yml/badge.svg)](https://github.com/AppsFlyerSDK/segment-appsflyer-ios/actions/workflows/unit-tests-workflow.yml)\r\n\r\n----------\r\n🛠 In order for us to provide optimal support, we would kindly ask you to submit any issues to support@appsflyer.com\r\n\r\n*When submitting an issue please specify your AppsFlyer sign-up (account) email , your app ID , production steps, logs, code snippets and any additional relevant information.*\r\n\r\n----------\r\n\r\n\r\n## Table of content\r\n\r\n- [Breaking changes](#breaking-changes)\r\n- [Installation](#installation)\r\n- [Manual mode](#manual)\r\n- [Usage](#usage) \r\n  - [Objective-C](#usage-obj-c)\r\n  - [Swift](#usage-swift)\r\n- [Get Conversion Data](#getconversiondata)\r\n  - [Objective-C](#gcd-obj-c)\r\n  - [Swift](#gcd-swift)\r\n- [Unified Deep linking](#DDL)\r\n    - [Swift](#ddl-swift)\r\n- [Install Attributed event](#install_attributed)\r\n- [Additional AppsFlyer SDK setup](#additional_setup)\r\n- [Send consent for DMA compliance](#dma_support)\r\n- [Examples](#examples) \r\n\r\n\r\n## \u003ca id=\"breaking-changes\"\u003e ❗ Breaking Changes\r\n\r\n- From version `6.3.2`, we use `xcframework` for iOS platform, then you need to use cocoapods version \u003e= 1.10\r\n\r\n## \u003ca id=\"installation\"\u003eInstallation\r\n\r\n### Cocoapods\r\n\r\nTo install the segment-appsflyer-ios integration:\r\n\r\n1. Simply add this line to your [CocoaPods](http://cocoapods.org) `Podfile`:\r\n\r\n**Production** version: \r\n```ruby\r\npod 'segment-appsflyer-ios', '6.15.1'\r\n```\r\n\r\n**Strict mode SDK** version: \r\n```ruby\r\npod 'segment-appsflyer-ios/Strict', '6.15.1'\r\n```\r\nUse the strict mode SDK to completely remove IDFA collection functionality and AdSupport framework dependencies (for example, when developing apps for kids).\r\n\r\n2. Run `pod install` in the project directory\r\n\r\n### Swift Package Manager\r\n  \r\n In XCode, go to **File** \u003e **Swift Package** \u003e **Add Package dependency...** And add https://github.com/AppsFlyerSDK/segment-appsflyer-ios for the package dependency url. \r\n\r\n## \u003ca id=\"manual\"\u003e Manual mode\r\nStarting version `6.8.0`, we support a manual mode to seperate the initialization of the AppsFlyer SDK and the start of the SDK. In this case, the AppsFlyer SDK won't start automatically, giving the developper more freedom when to start the AppsFlyer SDK. Please note that in manual mode, the developper is required to implement the API ``AppsFlyerLib.shared().start()`` in order to start the SDK. \r\n\u003cbr\u003eIf you are using CMP to collect consent data this feature is needed. See explanation [here](#dma_support).\r\n### Example:\r\n#### objective-c:  \r\n```objective-c\r\n  SEGAppsFlyerIntegrationFactory* factoryWithManualMode = [SEGAppsFlyerIntegrationFactory createWithManualMode:YES];\r\n``` \r\n#### swift  \r\n```swift\r\n  let factoryWithManualMode = SEGAppsFlyerIntegrationFactory.create(withManualMode: true);\r\n``` \r\nPlease look at the examples below to see how to use the manual mode with delegate. \\\r\nTo start the AppsFlyer SDK, use the `start()` API, like the following :\r\n#### objective-c:  \r\n```objective-c\r\n [[AppsFlyerLib shared] start];\r\n [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue: nil usingBlock:^(NSNotification * _Nonnull note) {\r\n     [[AppsFlyerLib shared] start];\r\n }]; \r\n``` \r\n#### swift  \r\n```swift\r\n AppsFlyerLib.shared().start()\r\n NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: nil) { Notification in\r\n     AppsFlyerLib.shared().start()\r\n }\r\n```   \r\nNote - The `addObserver` call ensures that every launch of the app (from background to foreground) is recorded correctly. \u003c/br\u003eSee a more detailed explanation [here](https://dev.appsflyer.com/hc/docs/integrate-ios-sdk#full-example)\r\n  \r\n## \u003ca id=\"usage\"\u003e Usage\r\n\r\nFirst of all, you must provide values for AppsFlyer Dev Key, Apple App ID (iTunes) and client secret in Segment's **dashboard** for AppsFlyer integration\r\n\r\n### \u003ca id=\"usage-obj-c\"\u003e Usage - Objective-C\r\n\r\nOpen `AppDelegate.h` and add:\r\n\r\n```objective-c\r\n#import \"SEGAppsFlyerIntegrationFactory.h\"\r\n```\r\n\r\nIn `AppDelegate.m` ➜ `didFinishLaunchingWithOptions`:\r\n\r\n```objective-c\r\n\r\n    // For ApsFlyer debug logs\r\n    [AppsFlyerLib shared].isDebug = YES;\r\n    \r\n//    [[AppsFlyerLib shared] waitForATTUserAuthorizationWithTimeoutInterval:60];\r\n    /*\r\n     Based on your needs you can either pass a delegate to process deferred\r\n     and direct deeplinking callbacks or disregard them.\r\n     If you choose to use the delegate, see extension to this class below\r\n     */\r\n    SEGAppsFlyerIntegrationFactory* factoryNoDelegate = [SEGAppsFlyerIntegrationFactory instance];\r\n//    SEGAppsFlyerIntegrationFactory* factoryWithDelegate = [SEGAppsFlyerIntegrationFactory createWithLaunchDelegate:self];\r\n\r\n// To use the manual mode, use the following method\r\n//    SEGAppsFlyerIntegrationFactory* factoryNoDelegate = [SEGAppsFlyerIntegrationFactory createWithManualMode:YES];\r\n//    SEGAppsFlyerIntegrationFactory* factoryWithDelegate = [SEGAppsFlyerIntegrationFactory createWithLaunchDelegate:self andManualMode:YES];\r\n\r\n    \r\n    SEGAnalyticsConfiguration *config = [SEGAnalyticsConfiguration configurationWithWriteKey:@\"SEGMENT_KEY\"];\r\n    [config use:factoryNoDelegate];\r\n//    [config use:factoryWithDelegate];  // use this if you want to get conversion data in the app. Read more in the integration guide\r\n    config.enableAdvertisingTracking = YES;       //OPTIONAL\r\n    config.trackApplicationLifecycleEvents = YES; //OPTIONAL\r\n    config.trackDeepLinks = YES;                  //OPTIONAL\r\n    config.trackPushNotifications = YES;          //OPTIONAL\r\n    [SEGAnalytics debug:YES];                     //OPTIONAL\r\n    [SEGAnalytics setupWithConfiguration:config];\r\n```\r\n\r\nIn `AppDelegate.m` ➜ `applicationDidBecomeActive`:\r\n```objective-c\r\n- (void)applicationDidBecomeActive:(UIApplication *)application {\r\n    // Getting user consent dialog. Please read https://dev.appsflyer.com/hc/docs/integrate-ios-sdk#enabling-app-tracking-transparency-att-support\r\n    if (@available(iOS 14, *)) {\r\n        [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {\r\n            //....\r\n        }];\r\n    }\r\n}\r\n```\r\n### \u003ca id=\"usage-swift\"\u003e Usage - Swift\r\n\r\n1. Open/Create `\u003cYour-App-name\u003e-Bridging-Header.h`  and add:\r\n\r\n```objective-c\r\n#import \"SEGAppsFlyerIntegrationFactory.h\"\r\n```\r\n![image](https://user-images.githubusercontent.com/50541317/90022182-e5768900-dcba-11ea-8bfd-180cc6f28700.png)\r\n\r\n2. Add path to the Bridging header under Build Settings \u003e Swift Compiler - General \u003e Objective-C Bridging Header\r\n![image](https://user-images.githubusercontent.com/50541317/90022174-e1e30200-dcba-11ea-8785-0303aebe75e2.png)\r\n\r\n3. Open `AppDelegate.swift` and add:\r\n\r\n```swift\r\nimport Segment\r\nimport AppsFlyerLib\r\nimport segment_appsflyer_ios\r\n```\r\n\r\n4. In `didFinishLaunchingWithOptions` add:\r\n```swift \r\n    // For AppsFLyer debug logs uncomment the line below\r\n    // AppsFlyerLib.shared().isDebug = true\r\n//    AppsFlyerLib.shared().waitForATTUserAuthorization(withTimeoutInterval: 60)\r\n\r\n    /*\r\n     Based on your needs you can either pass a delegate to process deferred\r\n     and direct deeplinking callbacks or disregard them.\r\n     If you choose to use the delegate, see extension to this class below\r\n     */\r\n//    let factoryWithDelegate : SEGAppsFlyerIntegrationFactory = SEGAppsFlyerIntegrationFactory.create(withLaunch: self)\r\n    let factoryNoDelegate = SEGAppsFlyerIntegrationFactory()\r\n    \r\n    /* If you want to use the manual mode, please use the following methods\r\n      with or without delegate */\r\n     //  let factoryWithDelegate : SEGAppsFlyerIntegrationFactory = SEGAppsFlyerIntegrationFactory.create(withLaunch: self, andManualMode:true)\r\n   // let factoryNoDelegate = SEGAppsFlyerIntegrationFactory.create(withManualMode: true)\r\n    \r\n    \r\n    // Segment initialization\r\n    let config = AnalyticsConfiguration(writeKey: \"SEGMENT_KEY\")\r\n//    config.use(factoryWithDelegate)  // use this if you want to get conversion data in the app. Read more in the integration guide\r\n    config.use(factoryNoDelegate)\r\n    config.enableAdvertisingTracking = true       //OPTIONAL\r\n    config.trackApplicationLifecycleEvents = true //OPTIONAL\r\n    config.trackDeepLinks = true                  //OPTIONAL\r\n    config.trackPushNotifications = true          //OPTIONAL\r\n    \r\n    Analytics.debug(false)\r\n    Analytics.setup(with: config)\r\n```\r\n\r\nIn `applicationDidBecomeActive` add:\r\n```swift\r\nfunc applicationDidBecomeActive(_ application: UIApplication) {\r\n    // If you want to collect IDFA, please add the code below and read https://support.appsflyer.com//hc/en-us/articles/207032066#integration-35-support-apptrackingtransparency-att\r\n    if #available(iOS 14, *) {\r\n        ATTrackingManager.requestTrackingAuthorization(completionHandler: { (status) in\r\n            // ...\r\n        })\r\n    }\r\n}\r\n```\r\nAppsFlyer integration responds to ```identify``` call.  To read more about it, visit [Segment identify method documentation](https://segment.com/docs/libraries/ios/#identify).\r\nIn identify call ```traits``` dictionary  ```setCustomerUserID``` and ```currencyCode```\r\n\r\n## \u003ca id=\"getconversiondata\"\u003e Get Conversion Data\r\n  \r\n  In order for Conversion Data to be sent to Segment, make sure you have enabled \"Track Attribution Data\" and specified App ID in AppsFlyer destination settings:\r\n  \r\n![image](https://user-images.githubusercontent.com/50541317/69795158-51b86780-11d4-11ea-9ab3-be3e669e4e3b.png)\r\n  \r\n### \u003ca id=\"gcd-obj-c\"\u003e Objective-C\r\n  \r\n    \r\n  In order to get Conversion Data you need to:\r\n  \r\n  1. Add `SEGAppsFlyerLibDelegate` protocol to your AppDelegate.h (or other) class\r\n```objective-c\r\n#import \u003cUIKit/UIKit.h\u003e\r\n#import \"SEGAppsFlyerIntegrationFactory.h\"\r\n\r\n@interface AppDelegate : UIResponder \u003cUIApplicationDelegate, SEGAppsFlyerLibDelegate\u003e\r\n```\r\n  2. Pass AppDelegate (or other) class when configuring Segment Analytics with AppsFlyer. Change line `[config use:[SEGAppsFlyerIntegrationFactory instance]];` to `[config use:[SEGAppsFlyerIntegrationFactory createWithLaunchDelegate:self]];`\r\n  3. In the class passed to the method above (AppDelegate.m by default) implement methods of the `SEGAppsFlyerLibDelegate` protocol. See sample code below:\r\n  \r\n```objective-c\r\n#import \"AppDelegate.h\"\r\n\r\n@interface AppDelegate ()\r\n\r\n@end\r\n\r\n@implementation AppDelegate\r\n\r\n-(void)onConversionDataSuccess:(NSDictionary*) installData {\r\n    BOOL first_launch_flag = [[installData objectForKey:@\"is_first_launch\"] boolValue];\r\n    NSString *status = [installData objectForKey:@\"af_status\"];\r\n    \r\n    if(first_launch_flag) {\r\n        if ([status isEqualToString:@\"Non-organic\"]){\r\n            NSString *sourceID = [installData objectForKey:@\"media_source\"];\r\n            NSString *campaign = [installData objectForKey:@\"campaign\"];\r\n            NSLog(@\"This is a non-organic install. Media source: %@ Campaign: %@\", sourceID, campaign);\r\n        } else {\r\n            NSLog(@\"This is an organic install\");\r\n        }\r\n    } else {\r\n        NSLog(@\"Not first launch\");\r\n    }\r\n};\r\n\r\n/**\r\n Any errors that occurred during the conversion request.\r\n */\r\n-(void)onConversionDataFail:(NSError *) error {\r\n    NSLog(@\"%@\", [error description]);\r\n};\r\n\r\n/**\r\n `attributionData` contains information about OneLink, deeplink.\r\n */\r\n- (void)onAppOpenAttribution:(NSDictionary *)attributionData{\r\n    NSLog(@\"onAppOpenAttribution\");\r\n    for(id key in attributionData){\r\n        NSLog(@\"onAppOpenAttribution: key=%@ value=%@\", key, [attributionData objectForKey:key]);\r\n    }\r\n};\r\n\r\n/**\r\n Any errors that occurred during the attribution request.\r\n */\r\n- (void)onAppOpenAttributionFailure:(NSError *)error{\r\n    NSLog(@\"%@\", [error description]);\r\n};\r\n\r\n// Rest of your AppDelegate code\r\n```\r\n\r\n\r\n### \u003ca id=\"gcd-swift\"\u003e Swift\r\n  \r\n  In order to get Conversion Data you need to:\r\n  \r\n  1. Add `SEGAppsFlyerLibDelegate` protocol to your AppDelegate (or other) class\r\n  2. Pass AppDelegate (or other) class when configuring Segment Analytics with AppsFlyer. If you use sample code from above, change line `config.use(factoryNoDelegate)` to `config.use(factoryWithDelegate)`\r\n  3. Implement methods of the protocol in the class, passed as a delegate. See sample code below where AppDelegate is used for that:\r\n  \r\n  ```swift\r\n  class AppDelegate: UIResponder, UIApplicationDelegate, SEGAppsFlyerLibDelegate {\r\n    \r\n    var window: UIWindow?\r\n    \r\n    func onConversionDataSuccess(_ conversionInfo: [AnyHashable : Any]) {\r\n        guard let first_launch_flag = conversionInfo[\"is_first_launch\"] as? Int else {\r\n            return\r\n        }\r\n        \r\n        guard let status = conversionInfo[\"af_status\"] as? String else {\r\n            return\r\n        }\r\n        \r\n        if(first_launch_flag == 1) {\r\n            if(status == \"Non-organic\") {\r\n                if let media_source = conversionInfo[\"media_source\"] , let campaign = conversionInfo[\"campaign\"]{\r\n                    print(\"This is a Non-Organic install. Media source: \\(media_source) Campaign: \\(campaign)\")\r\n                }\r\n            } else {\r\n                print(\"This is an organic install.\")\r\n            }\r\n        } else {\r\n            print(\"Not First Launch\")\r\n        }\r\n    }\r\n    \r\n    func onAppOpenAttribution(_ attributionData: [AnyHashable : Any]) {\r\n        print(\"Deep Link Data goes here:\")\r\n        if let data = attributionData{\r\n          print(\"\\(data)\")\r\n        }\r\n    }\r\n\r\n   func onConversionDataFail(_ error: Error) {\r\n        }\r\n\r\n    func onAppOpenAttributionFailure(_ error: Error?) {\r\n    }\r\n    //rest of you AppDelegate code\r\n  }\r\n  ```\r\n\r\n## \u003ca id=\"DDL\"\u003e Unified Deep linking\r\n### \u003ca id=\"ddl-swift\"\u003e Swift\r\nIn order to use Unified Deep linking you need to:\r\n  \r\n  1. Add `SEGAppsFlyerDeepLinkDelegate` protocol to your AppDelegate (or other) class\r\n  2. Pass AppDelegate (or other) class when configuring Segment Analytics with AppsFlyer. From the sample code above, change  factoryWithDelegate to :\r\n  ```swift\r\n  let factoryWithDelegate: SEGAppsFlyerIntegrationFactory = SEGAppsFlyerIntegrationFactory.create(withLaunch: self, andDeepLinkDelegate: self)\r\n  ```\r\n\r\n  3. Implement methods of the protocol in the class, passed as a delegate. See sample code below where AppDelegate is used for that:\r\n  \r\n```swift\r\nextension AppDelegate: SEGAppsFlyerDeepLinkDelegate {\r\n    func didResolveDeepLink(_ result: DeepLinkResult) {\r\n        print(result)\r\n    }\r\n}\r\n\r\n```\r\n\r\n\r\n## \u003ca id=\"install_attributed\"\u003e Install Attributed event\r\n\r\nIf you are working with networks that don't allow passing user level data to 3rd parties, you will need to apply code to filter out these networks before calling\r\n```objective-c\r\n// [self.analytics track:@\"Install Attributed\" properties:[properties copy]];\r\n```\r\n\r\n## \u003ca id=\"additional_setup\"\u003e Additional AppsFlyer SDK setup\r\n\r\n```objective-c\r\n@import AppsFlyerLib;\r\n\r\n...\r\n@implementation AppDelegate\r\n\r\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\r\n    \r\n    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(integrationDidStart:) name:SEGAnalyticsIntegrationDidStart object:nil];\r\n    ...\r\n}\r\n\r\n...\r\n\r\n- (void)integrationDidStart:(nonnull NSNotification *)notification {\r\n    NSString *integration = notification.object;\r\n    if ([integration isEqualToString:@\"AppsFlyer\"]) {\r\n        /// Additional AppsFlyer SDK setup goes below\r\n        /// All setup is optional\r\n        /// To set Apple App ID and AppsFlyer Dev Key use Segment dashboard\r\n        /// ...\r\n        /// Enable ESP support for specific URLs\r\n        [[AppsFlyerLib shared] setResolveDeepLinkURLs:@[@\"afsdktests.com\"]];\r\n        /// Disable printing SDK messages to the console log\r\n        [[AppsFlyerLib shared]  setIsDebug:NO];\r\n        /// `OneLink ID` from OneLink configuration\r\n        [[AppsFlyerLib shared]  setAppInviteOneLink:@\"one_link_id\"];\r\n    }\r\n}\r\n```\r\n\r\n## \u003ca id=\"dma_support\"\u003e Send consent for DMA compliance\r\nFor a general introduction to DMA consent data, see [here](https://dev.appsflyer.com/hc/docs/send-consent-for-dma-compliance).\u003cbe\u003e\r\nThe SDK offers two alternative methods for gathering consent data:\u003cbr\u003e\r\n- **Through a Consent Management Platform (CMP)**: If the app uses a CMP that complies with the [Transparency and Consent Framework (TCF) v2.2 protocol](https://iabeurope.eu/tcf-supporting-resources/), the SDK can automatically retrieve the consent details.\u003cbr\u003e\r\n\u003cbr\u003eOR\u003cbr\u003e\u003cbr\u003e\r\n- **Through a dedicated SDK API**: Developers can pass Google's required consent data directly to the SDK using a specific API designed for this purpose.\r\n### Use CMP to collect consent data\r\nA CMP compatible with TCF v2.2 collects DMA consent data and stores it in \u003ccode\u003eNSUserDefaults\u003c/code\u003e. To enable the SDK to access this data and include it with every event, follow these steps:\u003cbr\u003e\r\n\u003col\u003e\r\n  \u003cli\u003e Call \u003ccode\u003eAppsFlyerLib.shared().enableTCFDataCollection(true)\u003c/code\u003e to instruct the SDK to collect the TCF data from the device.\r\n  \u003cli\u003e Initialize \u003ccode\u003eSEGAppsFlyerIntegrationFactory\u003c/code\u003e using manual mode. This will allow us to delay the Conversion call in order to provide the SDK with the user consent.\r\n  \u003cli\u003e In the \u003ccode\u003eapplicationDidBecomeActive\u003c/code\u003e lifecycle method, use the CMP to decide if you need the consent dialog in the current session to acquire the consent data. If you need the consent dialog move to step 4; otherwise move to step 5.\r\n  \u003cli\u003e Get confirmation from the CMP that the user has made their consent decision and the data is available in \u003ccode\u003eNSUserDefaults\u003c/code\u003e.\r\n  \u003cli\u003e Call \u003ccode\u003eAppsFlyerLib.shared().start()\u003c/code\u003e.\r\n\u003c/ol\u003e\r\n\r\n\r\n```swift\r\nfunc application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -\u003e Bool {\r\n\r\n    // For AppsFLyer debug logs uncomment the line below\r\n    AppsFlyerLib.shared().isDebug = true\r\n    AppsFlyerLib.shared().waitForATTUserAuthorization(timeoutInterval: 60)\r\n    AppsFlyerLib.shared().enableTCFDataCollection(true)\r\n    let factoryWithDelegateAndManual: SEGAppsFlyerIntegrationFactory =SEGAppsFlyerIntegrationFactory.create(withLaunch: self, andDeepLinkDelegate: self, andManualMode: true)\r\n  \r\n    // Segment initialization\r\n    let config = AnalyticsConfiguration(writeKey: \"SEGMENT_KEY\")\r\n    config.use(factoryWithDelegateAndManual)\r\n    config.enableAdvertisingTracking = true       //OPTIONAL\r\n    config.trackApplicationLifecycleEvents = true //OPTIONAL\r\n    config.trackDeepLinks = true                  //OPTIONAL\r\n    config.trackPushNotifications = true          //OPTIONAL\r\n  \r\n    Analytics.debug(true)\r\n    Analytics.setup(with: config)\r\n    return true\r\n}\r\n\r\nfunc applicationDidBecomeActive(_ application: UIApplication) {\r\n    if(cmpManager!.hasConsent()){\r\n        //CMP manager already has consent ready - you can start\r\n        AppsFlyerLib.shared().start()\r\n    }else{\r\n        //CMP doesn't have consent data ready yet\r\n        //Waiting for CMP completion and data ready and then start\r\n        cmpManager?.withOnCmpButtonClickedCallback({ CmpButtonEvent in\r\n            AppsFlyerLib.shared().start()\r\n        })\r\n    }\r\n    \r\n    if #available(iOS 14, *) {\r\n        ATTrackingManager.requestTrackingAuthorization { (status) in\r\n            switch status {\r\n            case .denied:\r\n                print(\"AuthorizationSatus is denied\")\r\n            case .notDetermined:\r\n                print(\"AuthorizationSatus is notDetermined\")\r\n            case .restricted:\r\n                print(\"AuthorizationSatus is restricted\")\r\n            case .authorized:\r\n                print(\"AuthorizationSatus is authorized\")\r\n            @unknown default:\r\n                fatalError(\"Invalid authorization status\")\r\n            }\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n### Manually collect consent data\r\nIf your app does not use a CMP compatible with TCF v2.2, use the SDK API detailed below to provide the consent data directly to the SDK.\r\n\u003col\u003e\r\n  \u003cli\u003e Initialize \u003ccode\u003eSEGAppsFlyerIntegrationFactory\u003c/code\u003e using manual mode. This will allow us to delay the Conversion call in order to provide the SDK with the user consent.\r\n  \u003cli\u003e In the \u003ccode\u003eapplicationDidBecomeActive\u003c/code\u003e lifecycle method determine whether the GDPR applies or not to the user.\u003cbr\u003e\r\n  - If GDPR applies to the user, perform the following: \r\n      \u003col\u003e\r\n        \u003cli\u003e Given that GDPR is applicable to the user, determine whether the consent data is already stored for this session.\r\n            \u003col\u003e\r\n              \u003cli\u003e If there is no consent data stored, show the consent dialog to capture the user consent decision.\r\n              \u003cli\u003e If there is consent data stored continue to the next step.\r\n            \u003c/ol\u003e\r\n        \u003cli\u003e To transfer the consent data to the SDK create an AppsFlyerConsent object with the following parameters:\u003cbr\u003e\r\n          - \u003ccode\u003eforGDPRUserWithHasConsentForDataUsage\u003c/code\u003e- Indicates whether the user has consented to use their data for advertising purposes.\r\n          - \u003ccode\u003ehasConsentForAdsPersonalization\u003c/code\u003e- Indicates whether the user has consented to use their data for personalized advertising.\r\n        \u003cli\u003e Call \u003ccode\u003eAppsFlyerLib.shared().setConsentData(AppsFlyerConsent(forGDPRUserWithHasConsentForDataUsage: Bool, hasConsentForAdsPersonalization: Bool))\u003c/code\u003e. \r\n        \u003cli\u003e Call \u003ccode\u003eAppsFlyerLib.shared().start()\u003c/code\u003e.\r\n      \u003c/ol\u003e\u003cbr\u003e\r\n    - If GDPR doesn’t apply to the user perform the following:\r\n      \u003col\u003e\r\n        \u003cli\u003e Call \u003ccode\u003eAppsFlyerLib.shared().setConsentData(AppsFlyerConsent(nonGDPRUser: ()))\u003c/code\u003e.\r\n        \u003cli\u003e It is optional to initialize \u003ccode\u003eSEGAppsFlyerIntegrationFactory\u003c/code\u003e using manual mode not mandatory as before.\r\n      \u003c/ol\u003e\r\n\u003c/ol\u003e\r\n\r\n\r\n## \u003ca id=\"examples\"\u003e Examples\r\n\r\nThis project  has [4 examples](https://github.com/AppsFlyerSDK/segment-appsflyer-ios/tree/master/examples) for objective-C and Swift (with troubleshooting). To give it a try , clone this repo and from each example first run `pod install` to install project dependancies.\r\n\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fappsflyersdk%2Fsegment-appsflyer-ios","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fappsflyersdk%2Fsegment-appsflyer-ios","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fappsflyersdk%2Fsegment-appsflyer-ios/lists"}