Интеграция SDK

Узнайте, как инициализировать и запустить SDK iOS.

Прежде чем начать

  • Прежде чем выполнять интеграцию, необходимо установить SDK.
  • В этом документе приведены примеры реализации. Не забудьте заменить следующее:
    • <YOUR_DEV_KEY>: ключ разработчика AppsFlyer.
    • <APPLE_APP_ID>: идентификатор приложения Apple (без префикса id ).
    • Дополнительные заполнители при необходимости.

Инициализация iOS SDK

Шаг 1. Импорт зависимостей
Импортировать AppsFlyerLib:

// AppDelegate.h
#import <AppsFlyerLib/AppsFlyerLib.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@end
import UIKit
import AppsFlyerLib

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    // ...
}

Шаг 2. Инициализация SDK
In didFinishLaunchingWithOptions задайте идентификатор приложения Apple и ключ разработчика AppsFlyer:

[[AppsFlyerLib shared] setAppsFlyerDevKey:@"<YOUR_DEV_KEY>"];
[[AppsFlyerLib shared] setAppleAppID:@"<APPLE_APP_ID>"];
AppsFlyerLib.shared().appsFlyerDevKey = "<YOUR_DEV_KEY>"
AppsFlyerLib.shared().appleAppID = "<APPLE_APP_ID>"

Запуск SDK iOS

In applicationDidBecomeActive, call start:

[[AppsFlyerLib shared] start];
func applicationDidBecomeActive(_ application: UIApplication) {
    AppsFlyerLib.shared().start()
    // ...
}

Add SceneDelegate support

Необязательно
Выполните следующее, только если вы используете SceneDelegate:

In didFinishLaunchingWithOptionsдобавьте наблюдатель UIApplicationDidBecomeActiveNotification и настройте его на запуск start:

@implementation AppDelegate
    // SceneDelegate support - start AppsFlyer SDK
    - (void)sendLaunch:(UIApplication *)application {
    [[AppsFlyerLib shared] start];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // ...
    // SceneDelegate support
    [[NSNotificationCenter defaultCenter] addObserver:self
     selector:@selector(sendLaunch:)
     name:UIApplicationDidBecomeActiveNotification
     object:nil];
    // ...
    return YES;
}
// ...
@end
import UIKit
import AppsFlyerLib
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        ...
        // SceneDelegate support
        NotificationCenter.default.addObserver(self, selector: NSSelectorFromString("sendLaunch"), name: UIApplicationdidBecomeActiveNotification, object: nil)
        return true
    }
    // SceneDelegate support - start AppsFlyer SDK
    @objc func sendLaunch() {
        AppsFlyerLib.shared().start()
    }
// ...
}

Start with completion handler

Необязательно
Чтобы получить подтверждение, что SDK успешно запустился и отправил уведомление на серверы AppsFlyer, вызовите start с обработчиком завершения. Затем результат применения этого метода (SDK запущен / не запущен) можно обработать с помощью логических операторов.

[[AppsFlyerLib shared] startWithCompletionHandler:^(NSDictionary<NSString *,id> *dictionary, NSError *error) {
        if (error) {
            NSLog(@"%@", error);
            return;
        }
        if (dictionary) {
            NSLog(@"%@", dictionary);
            return;
        }
    }];
AppsFlyerLib.shared()?.start(completionHandler: { (dictionary, error) in
            if (error != nil){
                print(error ?? "")
                return
            } else {
                print(dictionary ?? "")
                return
            }
        })

Полный пример

#import "AppDelegate.h"
#import <AppsFlyerLib/AppsFlyerLib.h>
#import <UserNotifications/UserNotifications.h>
@interface AppDelegate ()
@end
@implementation AppDelegate
    // Start the AppsFlyer SDK
    - (void)sendLaunch:(UIApplication *)application {
    [[AppsFlyerLib shared] start];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    /** APPSFLYER INIT **/
    [AppsFlyerLib shared].appsFlyerDevKey = @"<YOUR_DEV_KEY>";
    [AppsFlyerLib shared].appleAppID = @"<APPLE_APP_ID>";
    /* Uncomment the following line to see AppsFlyer debug logs */
    // [AppsFlyerLib shared].isDebug = true;
  
    // SceneDelegate support
    [[NSNotificationCenter defaultCenter] addObserver:self
     selector:@selector(sendLaunch:)
     name:UIApplicationDidBecomeActiveNotification
     object:nil];
    if (@available(iOS 10, *)) {
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        center.delegate = self;
        [center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) {
        }];
    }

    else {
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes: UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    }

    [[UIApplication sharedApplication] registerForRemoteNotifications];
    return YES;
}

@end
import UIKit
import AppsFlyerLib
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        AppsFlyerLib.shared().appsFlyerDevKey = "<YOUR_DEV_KEY>"
        AppsFlyerLib.shared().appleAppID = "<APPLE_APP_ID>"
        /* Uncomment the following line to see AppsFlyer debug logs */
        // AppsFlyerLib.shared().isDebug = true
        // SceneDelegate support
        NotificationCenter.default.addObserver(self, selector: NSSelectorFromString("sendLaunch"), name: UIApplication.didBecomeActiveNotification, object: nil)
        return true
    }
    // SceneDelegate support
    @objc func sendLaunch() {
        AppsFlyerLib.shared().start()
    }
// ...
}

Ссылка на Github

Настройка Customer User ID (идентификатора клиента)

Необязательно
Customer User ID (CUID) — это уникальный идентификатор пользователя, созданный вне SDK владельцем приложения. Если он доступен SDK, его можно связать с установками и другими событиями внутри приложения. Эти события с меткой CUID могут быть сопоставлены с данными пользователя от других устройств и приложений.

Set the CUID

Чтобы настроить CUID:

[AppsFlyerLib shared].customerUserID = @"my user id";
AppsFlyerLib.shared().customerUserID = "my user id"

📘

Примечание

The Customer User ID must be set with every app launch.

Associate the CUID with the install event

If it’s important for you to associate the install event with the CUID, you should set to set the customerUserId до вызова метода start . Это связано с тем, что start отправляет событие установки в AppsFlyer. Если CUID установлен после вызова start, он не будет связан с событием установки.

- (void)applicationDidBecomeActive:(UIApplication *)application {
  	// Your custom logic of retrieving CUID
    NSString *customUserId = [[NSUserDefaults standardUserDefaults] stringForKey:@"customerUserId"];  
    if (customUserId != nil && ![customUserId  isEqual: @""]) {
        // Set CUID in AppsFlyer SDK for this session
        [AppsFlyerLib shared].customerUserID = customUserId; 
        // Start
        [[AppsFlyerLib shared] start]; 
    }
}
func applicationDidBecomeActive(_ application: UIApplication) {
  //  your logic to retrieve CUID
  let customUserId = UserDefaults.standard.string(forKey: "customUserId") 
  
  if(customUserId != nil && customUserId != ""){
     // Set CUID in AppsFlyer SDK for this session
    AppsFlyerLib.shared().customerUserID = customUserId    
    AppsFlyerLib.shared().start() // Start
  }
}

Log sessions

The SDK sends an af_app_opened message whenever the app is opened or brought to the foreground, providing that start is called in the didBecomeActive lifecycle event method. Before the message is sent, the SDK makes sure that the time passed since sending the last message is not smaller than a predefined interval.

Setting the time interval between app launches

Установлено minTimeBetweenSessions to the minimal time interval that must lapse between two af_app_opened messages. The default interval is 5 seconds.

Поддержка iOS 14

Далее описано, как настроить поддержку возможностей iOS 14+.

Enabling App Tracking Transparency (ATT) support

Начиная с iOS 14.5, доступом к IDFA управляет фреймворк ATT.
После включения поддержки ATT в SDK, ATT обрабатывает сбор IDFA на устройствах с iOS 14.5+.

🚧

Внимание!

Вызовите waitForATTUserAuthorization только если вы собираетесь вызвать requestTrackingAuthorization где-либо в вашем приложении.

Шаг 1. Настройка waitForATTUserAuthorization
При инициализации SDK до вызова start In applicationDidBecomeActive, call waitForATTUserAuthorization:

[[AppsFlyerLib shared] waitForATTUserAuthorizationWithTimeoutInterval:60];
AppsFlyerLib.shared().waitForATTUserAuthorization(timeoutInterval: 60)

Ссылка на Github

Установлено timeoutInterval так, чтобы у пользователей приложения было достаточно времени, чтобы увидеть запрос на ATT и отреагировать на него. Несколько примеров:

  • Если запрос на ATT отображается при запуске приложения, то 60 секунд должно хватить.
  • Если запрос на ATT отображается после инструкций, на выполнение которых уходит около двух минут, то следует установить интервал в 120 секунд.

Шаг 2. Вызов requestTrackingAuthorization
Вызовите requestTrackingAuthorization там, где хотите отобразить запрос:

- (void)didBecomeActiveNotification {
    // start is usually called here:
    // [[AppsFlyerLib shared] start]; 
    if @available(iOS 14, *) {
      
      [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
        NSLog(@"Status: %lu", (unsigned long)status);
      }];
    }
}
@objc func didBecomeActiveNotification() {
    // start is usually called here:
    // AppsFlyerLib.shared().start()
    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")
        }
      }
    }
}

Ссылка на Github

📘

Примечание

  • Вам необходимо импортировать фреймворк AppTrackingTransparency для вызова requestTrackingAuthorization.
  • Согласно документации Apple:
    • requestTrackingAuthorization вызывается, только если приложение находится в состоянии UIApplicationStateActive .
    • requestTrackingAuthorization не может вызываться из расширений приложения.

Customizing the ATT consent dialog

Диалоговое окно с запросом согласия на ATT можно настроить, изменив в проекте Xcode файл info.plist:

Подробные инструкции см. в документации компании Apple.

Attributing App Clips

Атрибуция Apple App Clips появилась в SDK iOS V6.0.8. Подробные инструкции см. в нашем руководстве по интеграции App Clips.

Sending SKAN postback copies to AppsFlyer

iOS 15
Настройте в приложении отправку копий постбэков в AppsFlyer.

Чтобы зарегистрировать конечную точку AppsFlyer:

  1. Добавьте NSAdvertisingAttributionReportEndpoint в файл приложения info.plist.
  2. В качестве значения ключа укажите https://appsflyer-skadnetwork.com/.

Согласно документации Apple, вы можете задать только одну конечную точку. Копии полученных постбэков доступны в отчете по копиям постбэков.

Включение режима отладки

Чтобы включить журналы отладки, задайте для isDebug значение true:

[AppsFlyerLib shared].isDebug = true;
AppsFlyerLib.shared().isDebug = true

📘

Примечание

Для просмотра полных журналов отладки необходимо задать isDebug до вызова других методов SDK.

См. пример.

🚧

Предупреждение

Чтобы не допустить утечки конфиденциальных данных, перед распространением приложения обязательно убедитесь, что журналы отладки отключены.

Тестирование интеграции

Подробные инструкции приведены в руководстве по тестированию интеграции SDK для iOS.