Search code examples
iosswiftxcodeappsflyerappsflyer-ios-sdk

Unable to record a non-organic install in AppsFlyer dashboard (iOS)


I have integrated AppsFlyer SDK in my iOS application and successfully added AppsFlyer event logging feature for several events. I am able to detect organic installs in my AppsFlyer dashboard and the events that have been triggered were successfully recorded. However, I am unable to generate a non-organic install either by using the Test Integration tool provided by AppsFlyer or by using a generated ad link. How do I generate a non-organic install for testing?

I first tried using the test integration tool provided by AppsFlyer. Using this method I performed the following steps :

  1. Added my device to the list of test devices in the AppsFlyer account.
  2. Clicked on run test, selected my test device and selected the Store option(App downloading source) as other (Xcode/TestFlight).
  3. Then I scanned the QR code in my device. This redirected the browser screen in my mac to a screen containing a button "next" that has to be clicked prior to opening the app.
  4. Downloaded the app using Xcode or TestFlight or Diawi link.
  5. Clicked on the "next" button and then opened the application in my device.
  6. Waited for a couple of minutes for the non-organic install to be recorded in the dashboard, but unfortunately it did not get recorded.

I then tried a different method to generate a non-organic install - using ad click. I created an ad link with a format of "https://app.appsflyer.com/<app_id>?pid=Test&c=Test&advertising_id=". I clicked on the link and installed the app followed by completing the flow to start appsflyer sdk. Unfortunately this did not reflect as a non-organic install.


Solution

  • I have found that it's essential to include ATT authorization in the app. Without ATT being enabled, the app will not record a non-organic installation.

    In order to include ATT, in the info.plist file, first include Privacy - Tracking usage description and provide an appropriate description for it

    Then, in the AppsFlyer SDK initialization, call the following function

    AppsFlyerLib.shared().waitForATTUserAuthorization(timeoutInterval: 60)
    

    The above function gives enough time for the user to accept the ATT consent. Adjust the time interval according to your app's needs. The objective here is to provide enough time for the user to accept the ATT consent prior to staring the SDK post initialization.

    Use the following function to prompt the user for ATT consent:

     func displayAttPrompt() {
        if #available(iOS 14, *) {
            ATTrackingManager.requestTrackingAuthorization { (status) in
                switch status {
                case .denied:
                    print("AuthorizationSatus is denied")
                case .notDetermined:
                    print("AuthorizationSatus is notDetermined")
                case .restricted:
                    print("AuthorizationSatus is restricted")
                case .authorized:
                    print("AuthorizationSatus is authorized")
                @unknown default:
                    fatalError("Invalid authorization status")
                }
                print("------------------------------\(ASIdentifierManager.shared().advertisingIdentifier)")
            }
        }
    }
    

    Include the ATT consent in the AppDelegate's applicationDidBecomeActive lifecycle function or right after the AppsFlyerLib.shared().waitForATTUserAuthorization(timeoutInterval: 60)

    In case, the ATT consent prompt does not appear, add a delay of 1s like so:

    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            self.displayAttPrompt() //function definition given in the previous code snippet
        }
    

    In order to start the SDK use the following code snippet

     AppsFlyerLib.shared().start(completionHandler: { (dictionary, error) in
                // your required code for error handling
            })