Примеры использования методов

Инициализация библиотеки с расширенной конфигурацией

Чтобы инициализировать библиотеку с расширенной стартовой конфигурацией:

  1. Инициализируйте объект класса AppMetricaConfiguration.
  2. Задайте настройки конфигурации с помощью методов класса AppMetricaConfiguration. Например, включите логирование или установите таймаут сессии.
  3. Передайте объект AppMetricaConfiguration в метод activate(with:) класса AppMetrica.

Настройки расширенной конфигурации применяются с момента инициализации библиотеки. Чтобы настроить библиотеку в процессе работы приложения, используйте методы класса AppMetrica.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : AnyObject]? = nil) -> Bool {
    // Creating an extended library configuration.
    if let configuration = AppMetricaConfiguration(apiKey: "API key") {
        // Setting up the configuration. For example, to enable logging.
        configuration.areLogsEnabled = true
        // ...
        // Initializing the AppMetrica SDK.
        AppMetrica.activate(with: configuration)
    }
}
  1. Инициализируйте объект класса AMAAppMetricaConfiguration.
  2. Задайте настройки конфигурации с помощью методов класса AMAAppMetricaConfiguration. Например, включите логирование или установите таймаут сессии.
  3. Передайте объект AMAAppMetricaConfiguration в метод +activateWithConfiguration: класса AMAAppMetrica.

Настройки расширенной конфигурации применяются с момента инициализации библиотеки. Чтобы настроить библиотеку в процессе работы приложения, используйте методы класса AMAAppMetrica.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Creating an extended library configuration.
    AMAAppMetricaConfiguration *configuration = [[AMAAppMetricaConfiguration alloc] initWithAPIKey:@"API key"];
    // Setting up the configuration. For example, to enable logging.
    configuration.logsEnabled = YES;
    // ...
    // Initializing the AppMetrica SDK.
    [AMAAppMetrica activateWithConfiguration:configuration];
    return YES;
}
Что такое API key?

API key — уникальный идентификатор приложения, который выдается в веб-интерфейсе AppMetrica при добавлении приложения. Он находится в разделе Настройки.

Отправка статистики на дополнительный API key

Отправка данных на дополнительный API key позволяет собирать для каждого API key свою статистику. Это можно использовать для управления доступом к информации. Например, чтобы предоставить доступ к статистике для аналитиков, можно продублировать отправку маркетинговых данных на дополнительный API key и предоставить им доступ к этой статистике. Так у них будет доступ только к той информации, которая им необходима.

Для отправки данных на дополнительный API key необходимо использовать репортеры. С помощью них можно отправлять события, сообщения об ошибках, профили и информацию о покупках в приложении. Репортеры могут работать без инициализации AppMetrica SDK.

Шаг 1. (Опционально) Инициализируйте репортер с расширенной конфигурацией

Важно

Инициализацию репортера с расширенной конфигурацией необходимо проводить до первого обращения к репортеру. Иначе репортер будет инициализирован без конфигурации.

Чтобы инициализировать репортер с расширенной конфигурацией:

  1. Инициализируйте объект класса MutableReporterConfiguration.
  2. Задайте настройки конфигурации с помощью методов класса MutableReporterConfiguration. Например, включите логирование или установите таймаут сессии.
  3. Передайте объект MutableReporterConfiguration в метод activateReporter(with:) класса AppMetrica.
  4. Конфигурация применяется для репортера с указанным API key. Для каждого дополнительного API key можно настроить свою конфигурацию.
// Creating an extended library configuration.
// To create it, pass an API key that is different from the app's API key.
if let reporterConfiguration = MutableReporterConfiguration(apiKey: "API key") {
    // Setting up the configuration. For example, to enable logging.
    reporterConfiguration.areLogsEnabled = true
    // ...
    // Initializing a reporter.
    AppMetrica.activateReporter(with: reporterConfiguration)
}
  1. Инициализируйте объект класса AMAMutableReporterConfiguration.
  2. Задайте настройки конфигурации с помощью методов класса AMAMutableReporterConfiguration. Например, включите логирование или установите таймаут сессии.
  3. Передайте объект AMAMutableReporterConfiguration в метод +activateReporterWithConfiguration: класса AMAAppMetrica.
  4. Конфигурация применяется для репортера с указанным API key. Для каждого дополнительного API key можно настроить свою конфигурацию.
// Creating an extended library configuration.
// To create it, pass an API key that is different from the app's API key.
AMAMutableReporterConfiguration *reporterConfiguration = [[AMAMutableReporterConfiguration alloc] initWithAPIKey:@"API key"];
// Setting up the configuration. For example, to enable logging.
reporterConfiguration.logsEnabled = YES;
// ...
// Initializing a reporter.
[AMAAppMetrica activateReporterWithConfiguration:[reporterConfiguration copy]];
Что такое API key?

API key — уникальный идентификатор приложения, который выдается в веб-интерфейсе AppMetrica при добавлении приложения. Он находится в разделе Настройки.

Шаг 2. Настройте отправку данных с помощью репортера

Чтобы отправить данные на другой API key:

  1. С помощью метода reporter(for:) класса AppMetrica получите объект, который реализует протокол AppMetricaReporting.

    Если репортер не был инициализирован с расширенной конфигурацией, то вызов данного метода произведет инициализацию репортера для указанного API key.

  2. Используйте методы протокола AppMetricaReporting для отправки событий и Revenue.

  3. Чтобы сессии отслеживались правильно, настройте отправку событий о начале и приостановке сессии для каждого репортера.

guard let reporter = AppMetrica.reporter(for: "API key") else {
    print("REPORT ERROR: Failed to create AppMetrica reporter")
    return // or return someDefaultValue or throw someError
}
reporter.resumeSession()
// ...
reporter.reportEvent(name: "Updates installed", onFailure: { (error) in
    print("REPORT ERROR: %@", error.localizedDescription)
})
// ...
reporter.pauseSession()
  1. С помощью метода +reporterForAPIKey: класса AMAAppMetrica получите объект, который реализует протокол AMAAppMetricaReporting.

    Если репортер не был инициализирован с расширенной конфигурацией, то вызов данного метода произведет инициализацию репортера для указанного API key.

  2. Используйте методы протокола AMAAppMetricaReporting для отправки событий и Revenue.

  3. Чтобы сессии отслеживались правильно, настройте отправку событий о начале и приостановке сессии для каждого репортера.

id<AMAAppMetricaReporting> reporter = [AMAAppMetrica reporterForAPIKey:@"API key"];
[reporter resumeSession];
// ...
[reporter reportEvent:@"Updates installed" onFailure:^(NSError *error) {
    NSLog(@"REPORT ERROR: %@", [error localizedDescription]);
}];
// ...
[reporter pauseSession];
Что такое API key?

API key — уникальный идентификатор приложения, который выдается в веб-интерфейсе AppMetrica при добавлении приложения. Он находится в разделе Настройки.

Отслеживание аварийных остановок приложения

Отчеты об аварийных остановках приложения отправляются по умолчанию.

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

Для этого установите значение false для свойства autoCrashTracking конфигурации AppMetricaCrashesConfiguration.

// Creating an crashes configuration.
let configuration = AppMetricaCrashesConfiguration()
// Disabling sending the information on crashes of the application.
configuration.autoCrashTracking = false
// Set the configuration for AppMetricaCrashes.
AppMetricaCrashes.crashes().setConfiguration(configuration)

Для этого установите значение NO для свойства autoCrashTracking конфигурации AMAAppMetricaCrashesConfiguration.

// Creating an crashes configuration.
AMAAppMetricaCrashesConfiguration *configuration = [[AMAAppMetricaCrashesConfiguration alloc] init];
// Disabling sending the information on crashes of the application.
configuration.autoCrashTracking = NO;
// Set the configuration in AppMetricaCrashes.
[[AMAAppMetricaCrashes crashes] setConfiguration:configuration];

Определение местоположения

AppMetrica умеет определять местоположение устройства. Точность определения зависит от конфигурации, с которой инициализируется библиотека:

  1. С включенной опцией locationTracking. Для iOS опция включена по умолчанию.

    Местоположение определяется с точностью до города. Информация доступна в отчетах и в Logs API.

    Приложение запрашивает доступ к GPS. Расход заряда аккумулятора может увеличиться.

  2. С отключенной опцией locationTracking.

    Местоположение определяется по IP-адресу с точностью до страны. Информация доступна в отчетах и в Logs API.

    Приложение не запрашивает доступ к GPS. Расход заряда аккумулятора не увеличивается.

    Примечание

    Если у вас включена маскировка IP-адреса, местоположение определяется так же с точностью до страны по немаскированной части IP-адреса.

По умолчанию AppMetrica SDK инициализируется с включенным locationTracking, но AppMetrica SDK не запрашивает разрешение на получение данных о местоположении. Это необходимо сделать самостоятельно с помощью методов класса CLLocationManager.

Чтобы инициализировать библиотеку с отключенным locationTracking, установите значение false для свойства locationTracking конфигурации AppMetricaConfiguration.

// Creating an extended library configuration.
if let configuration = AppMetricaConfiguration(apiKey: "API key") {
    // Disabling sending information about the location of the device.
    configuration.locationTracking = false
    // Initializing the AppMetrica SDK.
    AppMetrica.activate(with: configuration)
}

Чтобы отключить locationTracking после инициализации библиотеки, используйте свойство isLocationTrackingEnabled класса AppMetrica:

AppMetrica.isLocationTrackingEnabled = false

Чтобы инициализировать библиотеку с отключенным locationTracking, установите значение NO для свойства locationTracking конфигурации AMAAppMetricaConfiguration.

// Creating an extended library configuration.
AMAAppMetricaConfiguration *configuration = [[AMAAppMetricaConfiguration alloc] initWithAPIKey:@"API key"];
// Disabling sending information about the device location.
configuration.locationTracking = NO;
// Initializing the AppMetrica SDK.
[AMAAppMetrica activateWithConfiguration:configuration];

Чтобы отключить locationTracking после инициализации библиотеки, используйте метод +setLocationTrackingEnabled: класса AMAAppMetrica:

AMAAppMetrica.locationTrackingEnabled = NO;

Установка местоположения устройства вручную

Перед отправкой собственной информации о местоположении устройства убедитесь, что отправка отчетов была включена.

По умолчанию местоположение устройства определяется библиотекой.

Чтобы отправить собственную информацию о местоположении устройства, передайте объект CLLocation в свойство customLocation класса AppMetrica.

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    AppMetrica.customLocation = locations.last
}

Чтобы отправить собственную информацию о местоположении устройства с помощью стартовой конфигурации, передайте объект CLLocation в свойство customLocation конфигурации AppMetricaConfiguration.

// Creating an extended library configuration.
if let configuration = AppMetricaConfiguration(apiKey: "API key") {
  // Set a custom location.
  configuration.customLocation = CLLocation(latitude: 0, longitude: 0)
  // Initializing the AppMetrica SDK.
  AppMetrica.activate(with: configuration)
}

Чтобы отправить собственную информацию о местоположении устройства, передайте объект CLLocation в метод setCustomLocation класса AMAAppMetrica.

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{
    AMAAppMetrica.customLocation = newLocation;
}

Чтобы отправить собственную информацию о местоположении устройства с помощью стартовой конфигурации, передайте объект CLLocation в свойство customLocation конфигурации AMAAppMetricaConfiguration.

// Creating an extended library configuration.
AMAAppMetricaConfiguration *configuration = [[AMAAppMetricaConfiguration alloc] initWithAPIKey:@"API key"];
// Set a custom location.
configuration.customLocation = [[CLLocation alloc] initWithLatitude:0 longitude:0];
// Initializing the AppMetrica SDK.
[AMAAppMetrica activateWithConfiguration:configuration];

Отправка собственного события

Чтобы отправить собственное событие без вложенных параметров, передайте в метод reportEvent(name:onFailure:) класса AppMetrica следующие параметры:

  • name — короткое название или описание события.
  • onFailure — блок, в который передается ошибка. Если вы не хотите отслеживать ошибку, то передайте в качестве блока значение nil.
var message = "Updates installed"
AppMetrica.reportEvent(name: message, onFailure: { (error) in
    print("DID FAIL TO REPORT EVENT: %@", message)
    print("REPORT ERROR: %@", error.localizedDescription)
})

Чтобы отправить собственное событие без вложенных параметров, передайте в метод +reportEvent:onFailure: класса AMAAppMetrica следующие параметры:

  • message — короткое название или описание события.
  • onFailure — блок, в который передается ошибка. Если вы не хотите отслеживать ошибку, то передайте в качестве блока значение nil.
NSString *message = @"Updates installed";
[AMAAppMetrica reportEvent:message onFailure:^(NSError *error) {
    NSLog(@"DID FAIL REPORT EVENT: %@", message);
    NSLog(@"REPORT ERROR: %@", [error localizedDescription]);
}];

Отправка собственного события с вложенными параметрами

Чтобы отправить собственное событие с вложенными параметрами, передайте в метод reportEvent(name:parameters:onFailure:) класса AppMetrica следующие параметры:

  • name — короткое название или описание события.

  • parameters — вложенные параметры в виде пар «ключ-значение».

    Веб-интерфейс AppMetrica отображает до пяти уровней вложенности события. Если событие содержит шесть уровней и более, в отчете отобразятся пять верхних. С помощью API отчетов можно выгрузить до десяти уровней.

  • onFailure — блок, в который передается ошибка. Если вы не хотите отслеживать ошибку, то передайте в качестве блока значение nil.

var message = "Updates installed"
let params = ["key1": "value1", "key2": "value2"]
AppMetrica.reportEvent(name: message, parameters: params, onFailure: { (error) in
    print("DID FAIL REPORT EVENT: %@", message)
    print("REPORT ERROR: %@", error.localizedDescription)
})

Чтобы отправить собственное событие с вложенными параметрами, передайте в метод +reportEvent:parameters:onFailure: класса AMAAppMetrica следующие параметры:

  • message — короткое название или описание события.

  • parameters — вложенные параметры в виде пар «ключ-значение».

    Веб-интерфейс AppMetrica отображает до пяти уровней вложенности события. Если событие содержит шесть уровней и более, в отчете отобразятся пять верхних. С помощью API отчетов можно выгрузить до десяти уровней.

  • onFailure — блок, в который передается ошибка. Если вы не хотите отслеживать ошибку, то передайте в качестве блока значение nil.

NSString *message = @"Updates installed";
NSDictionary *params = @{@"key1": @"value1", @"key2": @"value2"};
[AMAAppMetrica reportEvent:message parameters:params onFailure:^(NSError *error) {
    NSLog(@"DID FAIL REPORT EVENT: %@", message);
    NSLog(@"REPORT ERROR: %@", [error localizedDescription]);
}];

Подробнее о событиях в разделе События.

Отправка события из JavaScript-кода WebView

AppMetrica SDK позволяет отправлять клиентские события из JavaScript-кода. Для этого требуется подключить модуль AppMetricaWebKit через систему управления зависимостями, которую вы используете.

Добавьте импорт:

import AppMetricaWebKit

Инициализируйте отправку вызовом метода setupWebViewReporting(with:onFailure:):

let userController = WKUserContentController()
AppMetrica.setupWebViewReporting(with: JSController(userContentController:userController), onFailure: nil)
userController.add(myHandler, name: myScriptName)
let configuration = WKWebViewConfiguration()
configuration.userContentController = userController;
let webView = WKWebView(frame: .zero, configuration: configuration)

Добавьте импорт:

#import <AppMetricaWebKit/AppMetricaWebKit.h>

Инициализируйте отправку вызовом метода +setupWebViewReporting:onFailure::

WKUserContentController *userController = [[WKUserContentController alloc] init];
[AMAAppMetrica setupWebViewReporting:[[AMAJSController alloc] initWithUserContentController:userController] onFailure:nil];
[userController addScriptMessageHandler:myHandler name:myScriptName];
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
configuration.userContentController = userController;
WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];

Метод необходимо вызывать до загрузки любого контента. Рекомендуется вызывать метод до создания вебвью и до добавления своих скриптов в WKUserContentController.

Для отправки события из JavaScript-кода используйте метод reportEvent(name, value) интерфейса AppMetrica:

function buttonClicked() {
  AppMetrica.reportEvent('Button clicked!', '{}');
}

Аргументы метода reportEvent:

  • name — строка. Не может быть null или пустым.
  • value — JSON-строка. Может быть null.

Отправка сообщения об ошибке

Для отправки сообщения об ошибке требуется подключить модуль AppMetricaCrashes через систему управления зависимостями, которую вы используете.

Чтобы отправить собственное сообщение об ошибке, необходимо добавить импорт:

import AppMetricaCrashes

Даллее используйте методы класса AppMetricaCrashes и протокола AppMetricaCrashReporting:

  • report(error:onFailure:)
  • report(error:options:onFailure:)
  • report(nserror:onFailure:)
  • report(nserror:options:onFailure:)

Для отправки можно использовать стандартный класс NSError, упрощенный класс AppMetricaError или протокол ErrorRepresentable.

Чтобы отправить собственное сообщение об ошибке, необходимо добавить импорт:

#import <AppMetricaCrashes/AppMetricaCrashes.h>

Далее используйте методы класса AMAAppMetricaCrashes и протокола AMAAppMetricaCrashReporting:

  • -reportError:onFailure:
  • -reportError:options:onFailure:
  • -reportNSError:onFailure:
  • -reportNSError:options:onFailure:

Для отправки можно использовать стандартный класс NSError, упрощенный класс AMAError или протокол AMAErrorRepresentable.

Пример с NSError

Если ошибки отправляются с использованием класса NSError, они группируются по домену domain и коду ошибки code.

let firstError = NSError(domain: "io.appmetrica.error-a", code: 12, userInfo: [
    BacktraceErrorKey: Thread.callStackReturnAddresses,
    NSLocalizedDescriptionKey: "Error A"
])
AppMetricaCrashes.crashes().report(nserror: firstError)
NSError *firstError = [NSError errorWithDomain:@"io.appmetrica.error-a"
                                          code:12
                                      userInfo:@{
                                           AMABacktraceErrorKey: NSThread.callStackReturnAddresses,
                                           NSLocalizedDescriptionKey: @"Error A"
                                      }];
[[AMAAppMetricaCrashes crashes] reportNSError:firstError onFailure:nil];

Пример c AppMetricaError

Если ошибки отправляются с использованием класса AppMetricaError или протокола ErrorRepresentable, они группируются по идентификатору identifier.

let underlyingError = AppMetricaError(identifier: "Underlying AMAError")
let error = AppMetricaError(
    identifier: "AMAError identifier",
    message: "Another custom message",
    parameters: [
        "foo": "bar"
    ],
    backtrace: Thread.callStackReturnAddresses,
    underlyingError: underlyingError
)
AppMetricaCrashes.crashes().report(error: error)

Если ошибки отправляются с использованием класса AMAError или протокола AMAErrorRepresentable, они группируются по идентификатору identifier.

AMAError *underlyingError = [AMAError errorWithIdentifier:@"Underlying AMAError"];
AMAError *error = [AMAError errorWithIdentifier:@"AMAError identifier"
                                        message:@"Another custom message"
                                     parameters:@{ @"foo": @"bar" }
                                      backtrace:NSThread.callStackReturnAddresses
                                underlyingError:underlyingError];
[[AMAAppMetricaCrashes crashes] reportError:error onFailure:nil];

Не используйте переменные значения в качестве идентификатора для группировки. Иначе количество групп будет увеличиваться и их будет сложно анализировать.

Отправка атрибутов профиля

Чтобы отправить атрибуты профиля, передайте в метод reportUserProfile(_:onFailure:) класса AppMetrica следующие параметры:

  • userProfile — объект UserProfile, который содержит массив обновлений атрибутов. Атрибуты профиля создаются с помощью методов класса ProfileAttribute.
  • onFailure — блок, в который передается ошибка. Если вы не хотите отслеживать ошибку, то передайте в качестве блока значение nil.
let profile = MutableUserProfile()
// Updating a single user profile attribute.
let timeLeftAttribute = ProfileAttribute.customCounter("time_left")
profile.apply(timeLeftAttribute.withDelta(-4.42))
// Updating multiple attributes.
profile.apply(from: [
    // Updating predefined attributes.
    ProfileAttribute.name().withValue("John"),
    ProfileAttribute.gender().withValue(GenderType.male),
    ProfileAttribute.birthDate().withAge(24),
    ProfileAttribute.notificationsEnabled().withValue(false),
    // Updating custom attributes.
    ProfileAttribute.customString("born_in").withValueIfUndefined("Moscow"),
    ProfileAttribute.customString("address").withValueReset(),
    ProfileAttribute.customNumber("age").withValue(24),
    ProfileAttribute.customCounter("logins_count").withDelta(1),
    ProfileAttribute.customBool("has_premium").withValue(true)
])
// ProfieID is set using the method of the AppMetrica class.
AppMetrica.userProfileID = "id"

// Sending profile attributes.
AppMetrica.reportUserProfile(profile, onFailure: { (error) in
    print("REPORT ERROR: %@", error.localizedDescription)
})

Чтобы отправить атрибуты профиля, передайте в метод +reportUserProfile:onFailure: класса AMAAppMetrica следующие параметры:

  • userProfile — объект AMAUserProfile, который содержит массив обновлений атрибутов. Атрибуты профиля создаются с помощью методов класса AMAProfileAttribute.
  • onFailure — блок, в который передается ошибка. Если вы не хотите отслеживать ошибку, то передайте в качестве блока значение nil.
AMAMutableUserProfile *profile = [[AMAMutableUserProfile alloc] init];
// Updating a single user profile attribute.
id<AMACustomCounterAttribute> timeLeftAttribute = [AMAProfileAttribute customCounter:@"time_left"];
[profile apply:[timeLeftAttribute withDelta:-4.42]];
// Updating multiple attributes.
[profile applyFromArray:@[
    // Updating predefined attributes.
    [[AMAProfileAttribute name] withValue:@"John"],
    [[AMAProfileAttribute gender] withValue:AMAGenderTypeMale],
    [[AMAProfileAttribute birthDate] withAge:24],
    [[AMAProfileAttribute notificationsEnabled] withValue:NO],
    // Updating custom attributes.
    [[AMAProfileAttribute customString:@"born_in"] withValueIfUndefined:@"Moscow"],
    [[AMAProfileAttribute customString:@"address"] withValueReset],
    [[AMAProfileAttribute customNumber:@"age"] withValue:24],
    [[AMAProfileAttribute customCounter:@"logins_count"] withDelta:1],
    [[AMAProfileAttribute customBool:@"has_premium"] withValue:YES]
]];
// ProfieID is set using the method of the AMAAppMetrica class.
[AMAAppMetrica setUserProfileID:@"id"];

// Sending profile attributes.
[AMAAppMetrica reportUserProfile:[profile copy] onFailure:^(NSError *error) {
    NSLog(@"Error: %@", error);
}];

Отправка ProfileId

Если отправка ProfileId не настроена, в веб-интерфейсе будет отображаться appmetrica_device_id.

Чтобы отправить ProfileId, используйте свойство userProfileID класса AppMetrica.

AppMetrica.userProfileID = "id"

Чтобы отправить ProfileId, используйте метод +setUserProfileID: класса AMAAppMetrica.

AMAAppMetrica.userProfileID = @"id";

Отправка ECommerce-событий

В AppMetrica нет возможности сегментировать ECommerce-события на «тестовые» и «не тестовые». Если для отладки покупок вы используете основной API key, то тестовые события будут попадать в общую статистику. Поэтому, чтобы отладить отправку ECommerce-событий, используйте отправку статистики на дополнительный API key с помощью репортера.

Шаг 1. Настройте отправку ECommerce-событий на тестовый API key

Для различных действий пользователя есть соответствующие типы ECommerce-событий. Чтобы создать конкретный тип события, используйте нужный метод класса ECommerce.

Ниже приведены примеры отправки конкретных типов событий:

Открытие страницы
// Creating a screen object.
let screen = ECommerceScreen(
        name: "ProductCardScreen",
        categoryComponents: ["Акции", "Красная цена"],
        searchQuery: "даниссимо кленовый сироп",
        payload: ["full_screen": "true"]
)
// Sending an e-commerce event.
if let reporter = AppMetrica.reporter(for: "Testing API key") {
   reporter.reportECommerce(.showScreenEvent(screen: screen))
}
// Creating a screen object.
AMAECommerceScreen *screen = [[AMAECommerceScreen alloc] initWithName:@"ProductCardScreen"
                                                   categoryComponents:@[ @"Акции", @"Красная цена" ]
                                                          searchQuery:@"даниссимо кленовый сироп"
                                                              payload:@{ @"full_screen": @"true" }];
// Sending an e-commerce event.
id<AMAAppMetricaReporting> reporter = [AMAAppMetrica reporterForAPIKey:@"Testing API key"];
[reporter reportECommerce:[AMAECommerce showScreenEventWithScreen:screen] onFailure:nil];
Просмотр карточки товара
// Creating a screen object.
let screen = ECommerceScreen(
        name: "ProductCardScreen",
        categoryComponents: ["Акции", "Красная цена"],
        searchQuery: "даниссимо кленовый сироп",
        payload: ["full_screen": "true"]
)
// Creating an actualPrice object.
let actualPrice = ECommercePrice(
        fiat: .init(unit: "USD", value: .init(string: "4.53")),
        internalComponents: [
            .init(unit: "wood", value: .init(string: "30570000")),
            .init(unit: "iron", value: .init(string: "26.89")),
            .init(unit: "gold", value: .init(string: "5.1")),
        ]
)
// Creating a product object.
let product = ECommerceProduct(
        sku: "779213",
        name: "Продукт творожный «Даниссимо» 5.9%, 130 г.",
        categoryComponents: ["Продукты", "Молочные продукты", "Йогурты"],
        payload: ["full_screen": "true"],
        actualPrice: actualPrice,
        originalPrice: .init(
                fiat: .init(unit: "USD", value: .init(string: "5.78")),
                internalComponents: [
                    .init(unit: "wood", value: .init(string: "30590000")),
                    .init(unit: "iron", value: .init(string: "26.92")),
                    .init(unit: "gold", value: .init(string: "5.5")),
                ]
        ),
        promoCodes: ["BT79IYX", "UT5412EP"]
)
// Sending an e-commerce event.
if let reporter = AppMetrica.reporter(for: "Testing API key") {
   reporter.reportECommerce(.showProductCardEvent(product: product, screen: screen))
}
// Creating a screen object.
AMAECommerceScreen *screen = [[AMAECommerceScreen alloc] initWithName:@"ProductCardScreen"
                                                   categoryComponents:@[ @"Акции", @"Красная цена" ]
                                                          searchQuery:@"даниссимо кленовый сироп"
                                                              payload:@{ @"full_screen": @"true" }];
// Creating an actualPrice object.
AMAECommerceAmount *actualFiat =
        [[AMAECommerceAmount alloc] initWithUnit:@"USD" value:[NSDecimalNumber decimalNumberWithString:@"4.53"]];
AMAECommerceAmount *woodActualPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"wood" value:[NSDecimalNumber decimalNumberWithString:@"30570000"]];
AMAECommerceAmount *ironActualPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"iron" value:[NSDecimalNumber decimalNumberWithString:@"26.89"]];
AMAECommerceAmount *goldActualPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"gold" value:[NSDecimalNumber decimalNumberWithString:@"5.1"]];
AMAECommercePrice *actualPrice = [[AMAECommercePrice alloc] initWithFiat:actualFiat
                                                      internalComponents:@[ woodActualPrice, ironActualPrice, goldActualPrice ]];
// Creating an originalPrice object.
AMAECommerceAmount *originalFiat =
        [[AMAECommerceAmount alloc] initWithUnit:@"USD" value:[NSDecimalNumber decimalNumberWithString:@"5.78"]];
AMAECommerceAmount *woodOriginalPrice =
         [[AMAECommerceAmount alloc] initWithUnit:@"wood" value:[NSDecimalNumber decimalNumberWithString:@"30590000"]];
AMAECommerceAmount *ironOriginalPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"iron" value:[NSDecimalNumber decimalNumberWithString:@"26.92"]];
AMAECommerceAmount *goldOriginalPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"gold" value:[NSDecimalNumber decimalNumberWithString:@"5.5"]];
AMAECommercePrice *originalPrice = [[AMAECommercePrice alloc] initWithFiat:originalFiat
                                                        internalComponents:@[ woodOriginalPrice, ironOriginalPrice, goldOriginalPrice ]];
// Creating a product object.
AMAECommerceProduct *product = [[AMAECommerceProduct alloc] initWithSKU:@"779213"
                                                                   name:@"Продукт творожный «Даниссимо» 5.9%, 130 г."
                                                     categoryComponents:@[ @"Продукты", @"Молочные продукты", @"Йогурты" ]
                                                                payload:@{ @"full_screen" : @"true" }
                                                            actualPrice:actualPrice
                                                          originalPrice:originalPrice
                                                             promoCodes:@[ @"BT79IYX", @"UT5412EP" ]];
// Sending an e-commerce event.
id<AMAAppMetricaReporting> reporter = [AMAAppMetrica reporterForAPIKey:@"Testing API key"];
[reporter reportECommerce:[AMAECommerce showProductCardEventWithProduct:product screen:screen] onFailure:nil];
Просмотр страницы товара
// Creating a screen object.
let screen = ECommerceScreen(
        name: "ProductCardScreen",
        categoryComponents: ["Акции", "Красная цена"],
        searchQuery: "даниссимо кленовый сироп",
        payload: ["full_screen": "true"]
)
// Creating an actualPrice object.
let actualPrice = ECommercePrice(
        fiat: .init(unit: "USD", value: .init(string: "4.53")),
        internalComponents: [
            .init(unit: "wood", value: .init(string: "30570000")),
            .init(unit: "iron", value: .init(string: "26.89")),
            .init(unit: "gold", value: .init(string: "5.1")),
        ]
)
// Creating a product object.
let product = ECommerceProduct(
        sku: "779213",
        name: "Продукт творожный «Даниссимо» 5.9%, 130 г.",
        categoryComponents: ["Продукты", "Молочные продукты", "Йогурты"],
        payload: ["full_screen": "true"],
        actualPrice: actualPrice,
        originalPrice: .init(
                fiat: .init(unit: "USD", value: .init(string: "5.78")),
                internalComponents: [
                    .init(unit: "wood", value: .init(string: "30590000")),
                    .init(unit: "iron", value: .init(string: "26.92")),
                    .init(unit: "gold", value: .init(string: "5.5")),
                ]
        ),
        promoCodes: ["BT79IYX", "UT5412EP"]
)
// Creating a referrer object.
let referrer = ECommerceReferrer(type: "button", identifier: "76890", screen: screen)
// Sending an e-commerce event.
if let reporter = AppMetrica.reporter(for: "Testing API key") {
   reporter.reportECommerce(.showProductDetailsEvent(product: product, referrer: referrer))
}
// Creating a screen object.
AMAECommerceScreen *screen = [[AMAECommerceScreen alloc] initWithName:@"ProductCardScreen"
                                                   categoryComponents:@[ @"Акции", @"Красная цена" ]
                                                          searchQuery:@"даниссимо кленовый сироп"
                                                              payload:@{ @"full_screen": @"true" }];

// Creating an actualPrice object.
AMAECommerceAmount *actualFiat =
        [[AMAECommerceAmount alloc] initWithUnit:@"USD" value:[NSDecimalNumber decimalNumberWithString:@"4.53"]];
AMAECommerceAmount *woodActualPrice =
         [[AMAECommerceAmount alloc] initWithUnit:@"wood" value:[NSDecimalNumber decimalNumberWithString:@"30570000"]];
AMAECommerceAmount *ironActualPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"iron" value:[NSDecimalNumber decimalNumberWithString:@"26.89"]];
AMAECommerceAmount *goldActualPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"gold" value:[NSDecimalNumber decimalNumberWithString:@"5.1"]];
AMAECommercePrice *actualPrice = [[AMAECommercePrice alloc] initWithFiat:actualFiat
                                                      internalComponents:@[ woodActualPrice, ironActualPrice, goldActualPrice ]];
// Creating an originalPrice object.
AMAECommerceAmount *originalFiat =
        [[AMAECommerceAmount alloc] initWithUnit:@"USD" value:[NSDecimalNumber decimalNumberWithString:@"5.78"]];
AMAECommerceAmount *woodOriginalPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"wood" value:[NSDecimalNumber decimalNumberWithString:@"30590000"]];
AMAECommerceAmount *ironOriginalPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"iron" value:[NSDecimalNumber decimalNumberWithString:@"26.92"]];
AMAECommerceAmount *goldOriginalPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"gold" value:[NSDecimalNumber decimalNumberWithString:@"5.5"]];
AMAECommercePrice *originalPrice = [[AMAECommercePrice alloc] initWithFiat:originalFiat
                                                        internalComponents:@[ woodOriginalPrice, ironOriginalPrice, goldOriginalPrice ]];
// Creating a product object.
AMAECommerceProduct *product = [[AMAECommerceProduct alloc] initWithSKU:@"779213"
                                                                   name:@"Продукт творожный «Даниссимо» 5.9%, 130 г."
                                                      categoryComponents:@[ @"Продукты", @"Молочные продукты", @"Йогурты" ]
                                                               payload:@{ @"full_screen" : @"true" }
                                                            actualPrice:actualPrice
                                                          originalPrice:originalPrice
                                                             promoCodes:@[ @"BT79IYX", @"UT5412EP" ]];
// Creating a referrer object.
AMAECommerceReferrer *referrer = [[AMAECommerceReferrer alloc] initWithType:@"button"
                                                                 identifier:@"76890"
                                                                     screen:screen];
// Sending an e-commerce event.
id<AMAAppMetricaReporting> reporter = [AMAAppMetrica reporterForAPIKey:@"Testing API key"];
[reporter reportECommerce:[AMAECommerce showProductDetailsEventWithProduct:product referrer:referrer] onFailure:nil];
Добавление или удаление товара из корзины
// Creating a screen object.
let screen = ECommerceScreen(
        name: "ProductCardScreen",
        categoryComponents: ["Акции", "Красная цена"],
        searchQuery: "даниссимо кленовый сироп",
        payload: ["full_screen": "true"]
)
// Creating an actualPrice object.
let actualPrice = ECommercePrice(
        fiat: .init(unit: "USD", value: .init(string: "4.53")),
        internalComponents: [
            .init(unit: "wood", value: .init(string: "30570000")),
            .init(unit: "iron", value: .init(string: "26.89")),
            .init(unit: "gold", value: .init(string: "5.1")),
        ]
)
// Creating a product object.
let product = ECommerceProduct(
        sku: "779213",
        name: "Продукт творожный «Даниссимо» 5.9%, 130 г.",
        categoryComponents: ["Продукты", "Молочные продукты", "Йогурты"],
        payload: ["full_screen": "true"],
        actualPrice: actualPrice,
        originalPrice: .init(
                fiat: .init(unit: "USD", value: .init(string: "5.78")),
                internalComponents: [
                    .init(unit: "wood", value: .init(string: "30590000")),
                    .init(unit: "iron", value: .init(string: "26.92")),
                    .init(unit: "gold", value: .init(string: "5.5")),
                ]
        ),
        promoCodes: ["BT79IYX", "UT5412EP"]
)
// Creating a referrer object.
let referrer = ECommerceReferrer(type: "button", identifier: "76890", screen: screen)
// Creating a cartItem object.
let addedItems = ECommerceCartItem(
        product: product,
        quantity: .init(string: "1"),
        revenue: actualPrice,
        referrer: referrer
)
// Sending an e-commerce event.
if let reporter = AppMetrica.reporter(for: "Testing API key") {
   reporter.reportECommerce(.addCartItemEvent(cartItem: addedItems))
   // Or:
   reporter.reportECommerce(.removeCartItemEvent(cartItem: addedItems))
}
// Creating a screen object.
AMAECommerceScreen *screen = [[AMAECommerceScreen alloc] initWithName:@"ProductCardScreen"
                                                   categoryComponents:@[ @"Акции", @"Красная цена" ]
                                                          searchQuery:@"даниссимо кленовый сироп"
                                                              payload:@{ @"full_screen": @"true" }];
// Creating an actualPrice object.
AMAECommerceAmount *actualFiat =
        [[AMAECommerceAmount alloc] initWithUnit:@"USD" value:[NSDecimalNumber decimalNumberWithString:@"4.53"]];
AMAECommerceAmount *woodActualPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"wood" value:[NSDecimalNumber decimalNumberWithString:@"30570000"]];
AMAECommerceAmount *ironActualPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"iron" value:[NSDecimalNumber decimalNumberWithString:@"26.89"]];
AMAECommerceAmount *goldActualPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"gold" value:[NSDecimalNumber decimalNumberWithString:@"5.1"]];
AMAECommercePrice *actualPrice = [[AMAECommercePrice alloc] initWithFiat:actualFiat
                                                      internalComponents:@[ woodActualPrice, ironActualPrice, goldActualPrice ]];
// Creating an originalPrice object.
AMAECommerceAmount *originalFiat =
        [[AMAECommerceAmount alloc] initWithUnit:@"USD" value:[NSDecimalNumber decimalNumberWithString:@"5.78"]];
AMAECommerceAmount *woodOriginalPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"wood" value:[NSDecimalNumber decimalNumberWithString:@"30590000"]];
AMAECommerceAmount *ironOriginalPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"iron" value:[NSDecimalNumber decimalNumberWithString:@"26.92"]];
AMAECommerceAmount *goldOriginalPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"gold" value:[NSDecimalNumber decimalNumberWithString:@"5.5"]];
AMAECommercePrice *originalPrice = [[AMAECommercePrice alloc] initWithFiat:originalFiat
                                                        internalComponents:@[ woodOriginalPrice, ironOriginalPrice, goldOriginalPrice ]];
// Creating a product object.
AMAECommerceProduct *product = [[AMAECommerceProduct alloc] initWithSKU:@"779213"
                                                                   name:@"Продукт творожный «Даниссимо» 5.9%, 130 г."
                                                     categoryComponents:@[ @"Продукты", @"Молочные продукты", @"Йогурты" ]
                                                                payload:@{ @"full_screen" : @"true" }
                                                            actualPrice:actualPrice
                                                          originalPrice:originalPrice
                                                             promoCodes:@[ @"BT79IYX", @"UT5412EP" ]];
// Creating a referrer object.
AMAECommerceReferrer *referrer = [[AMAECommerceReferrer alloc] initWithType:@"button"
                                                                 identifier:@"76890"
                                                                     screen:screen];
// Creating a cartItem object.
NSDecimalNumber *quantity = [NSDecimalNumber decimalNumberWithString:@"1"];
AMAECommerceCartItem *addedItems = [[AMAECommerceCartItem alloc] initWithProduct:product
                                                                        quantity:quantity
                                                                         revenue:actualPrice
                                                                        referrer:referrer];
// Sending an e-commerce event.
id<AMAAppMetricaReporting> reporter = [AMAAppMetrica reporterForAPIKey:@"Testing API key"];
[reporter reportECommerce:[AMAECommerce addCartItemEventWithItem:addedItems] onFailure:nil];
// Or:
[reporter reportECommerce:[AMAECommerce removeCartItemEventWithItem:addedItems] onFailure:nil];
Начало оформления и завершение покупки
// Creating a screen object.
let screen = ECommerceScreen(
        name: "ProductCardScreen",
        categoryComponents: ["Акции", "Красная цена"],
        searchQuery: "даниссимо кленовый сироп",
        payload: ["full_screen": "true"]
)
// Creating an actualPrice object.
let actualPrice = ECommercePrice(
        fiat: .init(unit: "USD", value: .init(string: "4.53")),
        internalComponents: [
            .init(unit: "wood", value: .init(string: "30570000")),
            .init(unit: "iron", value: .init(string: "26.89")),
            .init(unit: "gold", value: .init(string: "5.1")),
        ]
)
// Creating a product object.
let product = ECommerceProduct(
        sku: "779213",
        name: "Продукт творожный «Даниссимо» 5.9%, 130 г.",
        categoryComponents: ["Продукты", "Молочные продукты", "Йогурты"],
        payload: ["full_screen": "true"],
        actualPrice: actualPrice,
        originalPrice: .init(
                fiat: .init(unit: "USD", value: .init(string: "5.78")),
                internalComponents: [
                    .init(unit: "wood", value: .init(string: "30590000")),
                    .init(unit: "iron", value: .init(string: "26.92")),
                    .init(unit: "gold", value: .init(string: "5.5")),
                ]
        ),
        promoCodes: ["BT79IYX", "UT5412EP"]
)
// Creating a referrer object.
let referrer = ECommerceReferrer(type: "button", identifier: "76890", screen: screen)
// Creating a cartItem object.
let addedItems = ECommerceCartItem(
        product: product,
        quantity: .init(string: "1"),
        revenue: actualPrice,
        referrer: referrer
)
// Creating an order object.
let order = ECommerceOrder(
        identifier: "88528768",
        cartItems: [addedItems],
        payload: ["black_friday": "true"]
)
// Sending an e-commerce event.
if let reporter = AppMetrica.reporter(for: "Testing API key") {
   reporter.reportECommerce(.beginCheckoutEvent(order:order))
   reporter.reportECommerce(.purchaseEvent(order: order))
}
// Creating a screen object.
AMAECommerceScreen *screen = [[AMAECommerceScreen alloc] initWithName:@"ProductCardScreen"
                                                   categoryComponents:@[ @"Акции", @"Красная цена" ]
                                                          searchQuery:@"даниссимо кленовый сироп"
                                                              payload:@{ @"full_screen": @"true" }];
// Creating an actualPrice object.
AMAECommerceAmount *actualFiat =
        [[AMAECommerceAmount alloc] initWithUnit:@"USD" value:[NSDecimalNumber decimalNumberWithString:@"4.53"]];
AMAECommerceAmount *woodActualPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"wood" value:[NSDecimalNumber decimalNumberWithString:@"30570000"]];
AMAECommerceAmount *ironActualPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"iron" value:[NSDecimalNumber decimalNumberWithString:@"26.89"]];
AMAECommerceAmount *goldActualPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"gold" value:[NSDecimalNumber decimalNumberWithString:@"5.1"]];
AMAECommercePrice *actualPrice = [[AMAECommercePrice alloc] initWithFiat:actualFiat
                                                      internalComponents:@[ woodActualPrice, ironActualPrice, goldActualPrice ]];
// Creating an originalPrice object.
AMAECommerceAmount *originalFiat =
        [[AMAECommerceAmount alloc] initWithUnit:@"USD" value:[NSDecimalNumber decimalNumberWithString:@"5.78"]];
AMAECommerceAmount *woodOriginalPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"wood" value:[NSDecimalNumber decimalNumberWithString:@"30590000"]];
AMAECommerceAmount *ironOriginalPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"iron" value:[NSDecimalNumber decimalNumberWithString:@"26.92"]];
AMAECommerceAmount *goldOriginalPrice =
        [[AMAECommerceAmount alloc] initWithUnit:@"gold" value:[NSDecimalNumber decimalNumberWithString:@"5.5"]];
AMAECommercePrice *originalPrice = [[AMAECommercePrice alloc] initWithFiat:originalFiat
                                                        internalComponents:@[ woodOriginalPrice, ironOriginalPrice, goldOriginalPrice ]];
// Creating a product object.
AMAECommerceProduct *product = [[AMAECommerceProduct alloc] initWithSKU:@"779213"
                                                                   name:@"Продукт творожный «Даниссимо» 5.9%, 130 г."
                                                     categoryComponents:@[ @"Продукты", @"Молочные продукты", @"Йогурты" ]
                                                                payload:@{ @"full_screen" : @"true" }
                                                            actualPrice:actualPrice
                                                          originalPrice:originalPrice
                                                             promoCodes:@[ @"BT79IYX", @"UT5412EP" ]];
// Creating a referrer object.
AMAECommerceReferrer *referrer = [[AMAECommerceReferrer alloc] initWithType:@"button"
                                                                 identifier:@"76890"
                                                                     screen:screen];
// Creating a cartItem object.
NSDecimalNumber *quantity = [NSDecimalNumber decimalNumberWithString:@"1"];
AMAECommerceCartItem *addedItems = [[AMAECommerceCartItem alloc] initWithProduct:product
                                                                        quantity:quantity
                                                                         revenue:actualPrice
                                                                        referrer:referrer];
// Creating an order object.
AMAECommerceOrder *order = [[AMAECommerceOrder alloc] initWithIdentifier:@"88528768"
                                                               cartItems:@[ addedItems ]
                                                                 payload:@{ @"black_friday" : @"true"}];
// Sending an e-commerce event.
id<AMAAppMetricaReporting> reporter = [AMAAppMetrica reporterForAPIKey:@"Testing API key"];
[reporter reportECommerce:[AMAECommerce beginCheckoutEventWithOrder:order] onFailure:nil];
[reporter reportECommerce:[AMAECommerce purchaseEventWithOrder:order] onFailure:nil];

Шаг 2. Проверьте отчет тестового приложения

Совершите тестовые покупки в приложении. Через некоторое время в интерфейсе AppMetrica проверьте отчет «Анализ покупок». Убедитесь, что ECommerce-события отображаются в отчете.

Подробнее об отчете в разделе Анализ покупок.

Шаг 3. Настройте отправку на основной API key

После успешного тестирования настройте отправку ECommerce-событий на основной API key.

Чтобы отправить объект ECommerce на основной API key, используйте метода reportECommerce(_:onFailure:) класса AppMetrica.

// ...
// Sending an e-commerce event.
AppMetrica.reportECommerce(.showScreenEvent(screen: screen))

Чтобы отправить объект AMAECommerce на основной API key, используйте метода +reportECommerce:onFailure: класса AMAAppMetrica.

// ...
// Sending an e-commerce event.
[AMAAppMetrica reportECommerce:[AMAECommerce showScreenEventWithScreen:screen] onFailure:nil];

Отправка Revenue

AppMetrica поддерживает валидацию покупок, которые реализованы с помощью библиотеки StoreKit. Валидация позволяет фильтровать покупки, которые совершаются из взломанных приложений. Если валидация включена и покупка не проходит валидацию, она не отображается в отчетах.

Примечание

Чтобы покупки валидировались, включите валидацию в настройках. Подробнее в разделе Отправка In-App покупок на iOS.

Шаг 1. Протестируйте отправку Revenue

В AppMetrica нет возможности сегментировать Revenue на «тестовые» и «не тестовые». Если для отладки покупок вы используете основной API key, то тестовые покупки будут попадать в общую статистику. Поэтому, чтобы отладить отправку Revenue, используйте отправку статистики на дополнительный API key с помощью репортера.

Ниже описаны этапы отправки Revenue на дополнительный API key:

С валидацией

Чтобы покупки на iOS валидировались, в собственной реализации завершения транзакции настройте отправку поля transactionID и receiptData:

  1. Инициализируйте объект MutableRevenueInfo.
  2. Для валидации покупки укажите transactionID и receiptData. Их необходимо получить до вызова SKPaymentQueue.default().finishTransaction(transaction).
  3. Отправьте объект MutableRevenueInfo на тестовый API key с помощью репортера AppMetricaReporting. Подробнее о работе репортеров в разделе Отправка статистики на дополнительный API key.
 func completeTransaction(_ transaction: SKPaymentTransaction) {
     // ...
     let price = NSDecimalNumber(string: "2100.5")
     // Initializing the Revenue instance.
     let revenueInfo = MutableRevenueInfo(priceDecimal: price, currency: "BYN")
     revenueInfo.productID = "TV soundbar"
     revenueInfo.quantity = 2
     revenueInfo.payload = ["source": "AppStore"]
     // Set purchase information for validation.
     if let url = Bundle.main.appStoreReceiptURL, let data = try? Data(contentsOf: url), let transactionID = transaction.transactionIdentifier {
         revenueInfo.transactionID = transactionID
         revenueInfo.receiptData = data
     }
     // Sending the Revenue instance using reporter.
     guard let reporter = AppMetrica.reporter(for: "Testing API key") else {
        print("Failed to create AppMetrica reporter")
        return
     }
     reporter.reportRevenue(revenueInfo, onFailure: { (error) in
         print("Revenue error: \(error.localizedDescription)")
     })
     // Remove the transaction from the payment queue.
     SKPaymentQueue.default().finishTransaction(transaction)
}
  1. Инициализируйте объект AMAMutableRevenueInfo.
  2. Для валидации покупки укажите transactionID и receiptData. Их необходимо получить до вызова [[SKPaymentQueue defaultQueue] finishTransaction:transaction].
  3. Отправьте объект AMAMutableRevenueInfo на тестовый API key с помощью репортера AMAAppMetricaReporting. Подробнее о работе репортеров в разделе Отправка статистики на дополнительный API key.
 - (void)completeTransaction:(SKPaymentTransaction *)transaction
 {
     // ...
     NSDecimalNumber *price = [NSDecimalNumber decimalNumberWithString:@"2100.5"];
     // Initializing the Revenue instance.
     AMAMutableRevenueInfo *revenueInfo = [[AMAMutableRevenueInfo alloc] initWithPriceDecimal:price currency:@"BYN"];
     revenueInfo.productID = @"TV soundbar";
     revenueInfo.quantity = 2;
     revenueInfo.payload = @{ @"source": @"AppStore" };
     // Set purchase information for validation.
     revenueInfo.transactionID = transaction.transactionIdentifier;
     revenueInfo.receiptData = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];
     // Sending the Revenue instance using reporter.
     id<AMAAppMetricaReporting> reporter = [AMAAppMetrica reporterForAPIKey:@"Testing API key"];
     [reporter reportRevenue:[revenueInfo copy] onFailure:^(NSError *error) {
         NSLog(@"Revenue error: %@", error);
     }];
     // Remove the transaction from the payment queue.
     [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
 }
Без валидации

Чтобы отправить информацию о покупке без валидации:

  1. Инициализируйте объект MutableRevenueInfo.

  2. (Опционально) Чтобы группировать покупки по OrderID, укажите его в свойстве payload.

    Примечание

    Если идентификатор OrderID не указан, AppMetrica генерирует идентификатор автоматически.

  3. Отправьте объект MutableRevenueInfo на тестовый API key с помощью репортера AppMetricaReporting. Подробнее о работе репортеров в разделе Отправка статистики на дополнительный API key.

 let price = NSDecimalNumber(string: "2100.5")
 // Initializing the Revenue instance.
 let revenueInfo = MutableRevenueInfo(priceDecimal: price, currency: "BYN")
 revenueInfo.productID = "TV soundbar"
 revenueInfo.quantity = 2
 // To group purchases, set the OrderID parameter in the payload property.
 revenueInfo.payload = ["OrderID": "Identifier", "source": "AppStore"]
 // Sending the Revenue instance using reporter.
 if let reporter = AppMetrica.reporter(for: "Testing API key") {
    reporter.reportRevenue(revenueInfo, onFailure: { (error) in
        print("Revenue error: \(error.localizedDescription)")
    })
 }
  1. Инициализируйте объект AMAMutableRevenueInfo.

  2. (Опционально) Чтобы группировать покупки по OrderID, укажите его в свойстве payload.

    Примечание

    Если идентификатор OrderID не указан, AppMetrica генерирует идентификатор автоматически.

  3. Отправьте объект AMAMutableRevenueInfo на тестовый API key с помощью репортера AMAAppMetricaReporting. Подробнее о работе репортеров в разделе Отправка статистики на дополнительный API key.

 NSDecimalNumber *price = [NSDecimalNumber decimalNumberWithString:@"2100.5"];
 // Initializing the Revenue instance.
 AMAMutableRevenueInfo *revenueInfo = [[AMAMutableRevenueInfo alloc] initWithPriceDecimal:price currency:@"BYN"];
 revenueInfo.productID = @"TV soundbar";
 revenueInfo.quantity = 2;
 // Setting the OrderID parameter in the payload property to group purchases
 revenueInfo.payload = @{ @"OrderID": @"Identifier", @"source": @"AppStore" };
 // Sending the Revenue instance using reporter.
 id<AMAAppMetricaReporting> reporter = [AMAAppMetrica reporterForAPIKey:@"Testing API key"];
 [reporter reportRevenue:[revenueInfo copy] onFailure:^(NSError *error) {
     NSLog(@"Revenue error: %@", error);
 }];

Шаг 2. Настройте отправку Revenue на основной API key

После успешного тестирования настройте отправку Revenue на основной API key.

Чтобы отправить объект MutableRevenueInfo на основной API key, используйте метод reportRevenue(_:onFailure:) класса AppMetrica.

// ...
// Sending the Revenue instance.
AppMetrica.reportRevenue(revenueInfo, onFailure: { (error) in
    print("Revenue error: \(error)")
})

Чтобы отправить объект AMAMutableRevenueInfo на основной API key, используйте метод +reportRevenue:onFailure: класса AMAAppMetrica.

// ...
// Sending the Revenue instance.
[AMAAppMetrica reportRevenue:[revenueInfo copy] onFailure:^(NSError *error) {
   NSLog(@"Revenue error: %@", error);
}];

Установка длительности таймаута сессии

По умолчанию длительность таймаута сессии равна 10 секундам. Это минимально допустимое значение свойства sessionTimeout.

Чтобы изменить длительность таймаута, передайте значение в секундах в свойство sessionTimeout конфигурации AppMetricaConfiguration.

// Creating an extended library configuration.
if let configuration = AppMetricaConfiguration(apiKey: "API key") {
    // Setting the session timeout.
    configuration.sessionTimeout = 15
    // Initializing the AppMetrica SDK.
    AppMetrica.activate(with: configuration)
}

Чтобы изменить длительность таймаута, передайте значение в секундах в свойство sessionTimeout конфигурации AMAAppMetricaConfiguration.

// Creating an extended library configuration.
AMAAppMetricaConfiguration *configuration = [[AMAAppMetricaConfiguration alloc] initWithAPIKey:@"API key"];
// Setting the session timeout.
configuration.sessionTimeout = 15;
// Initializing the AppMetrica SDK.
[AMAAppMetrica activateWithConfiguration:configuration];

Установка версии приложения

По умолчанию версия приложения задается в файле Info.plist (CFBundleShortVersionString).

Чтобы указать версию приложения из кода, передайте версию приложения в свойство appVersion конфигурации AppMetricaConfiguration.

// Creating an extended library configuration.
if let configuration = AppMetricaConfiguration(apiKey: "API key") {
    // Setting the app version.
    configuration.appVersion = "1.13.2"
    // Initializing the AppMetrica SDK.
    AppMetrica.activate(with: configuration)
}

Чтобы указать версию приложения из кода, передайте версию приложения в свойство appVersion конфигурации AMAAppMetricaConfiguration.

// Creating an extended library configuration.
AMAAppMetricaConfiguration *configuration = [[AMAAppMetricaConfiguration alloc] initWithAPIKey:@"API key"];
// Setting the app version.
configuration.appVersion = @"1.13.2";
// Initializing the AppMetrica SDK.
[AMAAppMetrica activateWithConfiguration:configuration];

Важно

Начиная с версии AppMetrica SDK iOS 4.0, отслеживание открытия приложения через deeplink работает автоматически. Для остальных вариантов настройте отслеживание вручную:

  • Версия AppMetrica SDK iOS ниже 4.0. Настройка отслеживания deeplink для UIApplicationDelegate.
  • Настройка отслеживания deeplink для UISceneDelegate (AppMetrica не отслеживает такие открытия автоматически).

Отслеживание открытий необходимо для корректного трекинга ремаркетинг-кампаний.

Примечание

Для работы с Universal Links добавьте их поддержку в вашем приложении.

UISceneDelegate

Чтобы вручную отслеживать открытия приложения с помощью Universal Link/deeplink, в UISceneDelegate в метод scene:willConnectToSession:options: добавьте код:

- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session
options:(UISceneConnectionOptions *)connectionOptions
{
  // Universal Link
  NSUserActivity *userActivity = [[connectionOptions.userActivities allObjects] firstObject];
  if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
    [AMAAppMetrica trackOpeningURL:context.URL];
  }
  else {
    // Deeplink
    UIOpenURLContext *context = [[connectionOptions.URLContexts allObjects] firstObject];
    if (context != nil) {
      [AMAAppMetrica trackOpeningURL:context.URL];
    }
  }
}

Чтобы вручную отслеживать открытия приложения с помощью Universal Link/deeplink в запущенном приложении, используйте код:

- (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity
{
  NSURL *url = userActivity.webpageURL;
  if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
    [AMAAppMetrica trackOpeningURL:context.URL];
  }
}

- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts
{
  UIOpenURLContext *context = [[URLContexts allObjects] firstObject];
  if (context != nil) {
    [AMAAppMetrica trackOpeningURL:context.URL];
  }
}

Чтобы вручную отслеживать открытия приложения с помощью Universal Link/deeplink, в UISceneDelegate в метод scene(_:willConnectTo:options:) добавьте код:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    // Universal Link
    if let userActivity = connectionOptions.userActivities.first {
        if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
           let url = userActivity.webpageURL {
            AppMetrica.trackOpeningURL(url)
        }
    }
    
    // Deep Link
    if let context = connectionOptions.urlContexts.first {
        AppMetrica.trackOpeningURL(context.url)
    }
}

Чтобы вручную отслеживать открытия приложения с помощью Universal Link/deeplink в запущенном приложении, используйте код:

func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
    guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
          let url = userActivity.webpageURL else { return }
    AppMetrica.trackOpeningURL(url)
}

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    guard let context = URLContexts.first else { return }
    AppMetrica.trackOpeningURL(context.url)
}

UIApplicationDelegate

Важно

Ручная настройка отслеживания с UIApplicationDelegate актуальна для версии AppMetrica SDK iOS ниже 4.0.

Чтобы вручную отслеживать открытия приложения с помощью Universal Link/deeplink, используйте метод +trackOpeningURL: класса AMAAppMetrica.

Чтобы вручную отслеживать открытия приложения с помощью deeplink или обработку deeplink в запущенном приложении, используйте UIApplicationDelegate и добавьте следующие изменения:

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
    [AMAAppMetrica trackOpeningURL:url];
    return YES;
}

// Delegate for tracking Universal links.
- (BOOL)application:(UIApplication *)application
    continueUserActivity:(NSUserActivity *)userActivity
    restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
    if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
        [AMAAppMetrica trackOpeningURL:userActivity.webpageURL];
    }
    return YES;
}

Чтобы вручную отслеживать открытия приложения с помощью Universal Link/deeplink, используйте метод +trackOpeningURL: класса AMAAppMetrica.

Чтобы вручную отслеживать открытия приложения с помощью deeplink или обработку deeplink в запущенном приложении, используйте UIApplicationDelegate и добавьте следующие изменения:

func application(_ application: UIApplication, openURL url: URL, sourceApplication: String?, annotation: AnyObject) -> Bool {
    AppMetrica.trackOpeningURL(url)
    return true
}

// Delegate for tracking Universal links.
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
        if let url = userActivity.webpageURL {
            AppMetrica.trackOpeningURL(url)
        }
    }
    return true
}

Узнайте больше

Учет новых пользователей

По умолчанию в момент первого запуска приложения все пользователи определяются как новые. Если AppMetrica SDK подключается к приложению, у которого уже есть активные пользователи, то для корректного отслеживания статистики можно настроить учет новых и старых пользователей.

Для этого необходимо инициализировать AppMetrica SDK, используя расширенную стартовую конфигурацию AMAAppMetricaConfiguration.

BOOL isFirstLaunch = NO;
// Creating an extended library configuration.
AMAAppMetricaConfiguration *configuration = [[AMAAppMetricaConfiguration alloc] initWithAPIKey:@"API key"];
// Implement the logic for detecting whether the app is starting for the first time.
// For example, you can check for files (settings, databases, and so on),
// which the app creates on its first launch.
if (conditions) {
    isFirstLaunch = YES;
}
configuration.handleFirstActivationAsUpdate = !isFirstLaunch;
// Initializing the AppMetrica SDK.
[AMAAppMetrica activateWithConfiguration:configuration];

Для этого необходимо инициализировать AppMetrica SDK, используя расширенную стартовую конфигурацию AppMetricaConfiguration.

var isFirstLaunch = false
// Creating an extended library configuration.
guard let configuration = AppMetricaConfiguration(apiKey: "API key") else {
    print("AppMetricaConfiguration initialization failed.")
    return // or return someDefaultValue or throw someError
}
// Implement the logic for detecting whether the app is starting for the first time.
// For example, you can check for files (settings, databases, and so on),
// which the app creates on its first launch.
if conditions {
    isFirstLaunch = true
}
configuration.handleFirstActivationAsUpdate = !isFirstLaunch
// Initializing the AppMetrica SDK.
AppMetrica.activate(with: configuration)

Отключение и включение отправки статистики

Если для отправки статистических данных требуется согласие пользователя, необходимо инициализировать библиотеку с отключенной опцией отправки статистики.

Для этого установите значение NO для свойства dataSendingEnabled конфигурации AMAAppMetricaConfiguration.

// Creating an extended library configuration.
AMAAppMetricaConfiguration *configuration = [[AMAAppMetricaConfiguration alloc] initWithAPIKey:@"API key"];
// Disabling sending statistics.
configuration.dataSendingEnabled = NO;
// Initializing the AppMetrica SDK.
[AMAAppMetrica activateWithConfiguration:configuration];

После того как пользователь дал согласие на отправку статистики (например, в настройках приложения или в соглашении при первом открытии), необходимо включить отправку с помощью метода +setDataSendingEnabled: класса AMAAppMetrica.

// Checking the status of the boolean variable. It shows the user confirmation.
if (flag) {
    // Enabling sending statistics.
    [AMAAppMetrica setDataSendingEnabled:YES];
}

Для этого установите значение false для свойства dataSendingEnabled конфигурации AppMetricaConfiguration.

// Creating an extended library configuration.
if let configuration = AppMetricaConfiguration(apiKey: "API key") {
    // Disabling sending statistics.
    configuration.dataSendingEnabled = false
    // Initializing the AppMetrica SDK.
    AppMetrica.activate(with: configuration)
}

После того как пользователь дал согласие на отправку статистики (например, в настройках приложения или в соглашении при первом открытии), необходимо включить отправку с помощью метода setDataSendingEnabled(_:) класса AppMetrica.

// Checking the status of the boolean variable. It shows the user confirmation.
if flag {
    // Enabling sending statistics.
    AppMetrica.setDataSendingEnabled(true);
}

Пример оповещения

Для информирования пользователей вы можете использовать любой текст. Например:

Это приложение использует сервис аналитики AppMetrica, предоставляемый компанией ООО «ЯНДЕКС», 119021, Россия, Москва, ул. Л. Толстого, 16 (далее — Яндекс) на Условиях использования сервиса.

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

Информация об использовании вами данного приложения, собранная при помощи инструментов AppMetrica, в обезличенном виде будет передаваться Яндексу и храниться на сервере Яндекса в ЕС и Российской Федерации. Яндекс будет обрабатывать эту информацию для предоставления статистики использования вами приложения, составления для нас отчетов о работе приложения, и предоставления других услуг.

Получение различных идентификаторов AppMetrica SDK

Чтобы получить различные идентификаторы AppMetrica SDK (DeviceId, DeviceIdHash, UUID) используйте метод requestStartupIdentifiersWithKeys() / requestStartupIdentifiers(). Для получения appmetrica_device_id нужно запрашивать DeviceIdHash.

AMAIdentifiersCompletionBlock block = ^(NSDictionary<AMAStartupKey,id> * _Nullable identifiers, NSError * _Nullable error) {
    if (identifiers[kAMADeviceIDHashKey] != nil) {
        NSLog(@"deviceIDHash = %@", identifiers[kAMADeviceIDHashKey]);
    }
    if (identifiers[kAMADeviceIDKey] != nil) {
        NSLog(@"deviceID = %@", identifiers[kAMADeviceIDKey]);
    }
    if (identifiers[kAMAUUIDKey] != nil) {
        NSLog(@"uuid = %@", identifiers[kAMAUUIDKey]);
    }
};
[AMAAppMetrica requestStartupIdentifiersWithKeys:@[kAMADeviceIDHashKey, kAMADeviceIDKey, kAMAUUIDKey] completionQueue:nil completionBlock:block];
// Specifying the keys for which we need to get identifiers
let keys: [StartupKey] = [StartupKey.deviceIDKey, StartupKey.deviceIDHashKey, StartupKey.uuidKey]

// Specifying the queue on which the completion handler will be executed (for example, the main thread)
let queue = DispatchQueue.main

// Requesting IDs
AppMetrica.requestStartupIdentifiers(for: keys, on: queue) { identifiers, error in
    if let error = error {
        print("Произошла ошибка: \(error.localizedDescription)")
    } else if let identifiers = identifiers {
        // Processing the received IDs
        if let deviceIDHash = identifiers[StartupKey.deviceIDHashKey] as? String {
            print("AppMetrica deviceIDHash: \(deviceIDHash)")
        }
        if let deviceID = identifiers[StartupKey.deviceIDKey] as? String {
            print("AppMetrica deviceID: \(deviceID)")
        }
        if let uuid = identifiers[StartupKey.uuidKey] as? String {
            print("AppMetrica uuid: \(uuid)")
        }
    }
}  

Если вы не нашли ответ на свой вопрос, то вы можете задать его через форму обратной связи. Пожалуйста, опишите возникшую проблему как можно подробнее. Если возможно, приложите скриншот.

Написать в службу поддержки