Примеры использования методов
- Инициализация библиотеки с расширенной конфигурацией
- Отправка статистики на дополнительный API key
- Отслеживание аварийных остановок приложения
- Определение местоположения
- Установка местоположения устройства вручную
- Отправка собственного события
- Отправка собственного события с вложенными параметрами
- Отправка события из JavaScript-кода WebView
- Отправка собственного сообщения об ошибке
- Отправка ProfileId
- Отправка атрибутов профиля
- Отправка ECommerce-событий
- Отправка Revenue
- Отправка Ad Revenue
- Установка длительности тайм-аута сессии
- Установка версии приложения
- Отслеживание открытий приложения с помощью deeplink
- Учет новых пользователей
- Отключение и включение отправки статистики
- Получение различных идентификаторов AppMetrica SDK
Инициализация библиотеки с расширенной конфигурацией
Чтобы инициализировать библиотеку с расширенной стартовой конфигурацией:
- Инициализируйте объект класса
AppMetricaConfiguration
. - Задайте настройки конфигурации с помощью методов класса
AppMetricaConfiguration
. Например, включите логирование или установите таймаут сессии. - Передайте объект
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)
}
}
- Инициализируйте объект класса
AMAAppMetricaConfiguration
. - Задайте настройки конфигурации с помощью методов класса
AMAAppMetricaConfiguration
. Например, включите логирование или установите таймаут сессии. - Передайте объект
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. (Опционально) Инициализируйте репортер с расширенной конфигурацией
Важно
Инициализацию репортера с расширенной конфигурацией необходимо проводить до первого обращения к репортеру. Иначе репортер будет инициализирован без конфигурации.
Чтобы инициализировать репортер с расширенной конфигурацией:
- Инициализируйте объект класса
MutableReporterConfiguration
. - Задайте настройки конфигурации с помощью методов класса
MutableReporterConfiguration
. Например, включите логирование или установите таймаут сессии. - Передайте объект
MutableReporterConfiguration
в методactivateReporter(with:)
классаAppMetrica
. - Конфигурация применяется для репортера с указанным 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)
}
- Инициализируйте объект класса
AMAMutableReporterConfiguration
. - Задайте настройки конфигурации с помощью методов класса
AMAMutableReporterConfiguration
. Например, включите логирование или установите таймаут сессии. - Передайте объект
AMAMutableReporterConfiguration
в метод+activateReporterWithConfiguration:
классаAMAAppMetrica
. - Конфигурация применяется для репортера с указанным 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:
-
С помощью метода
reporter(for:)
классаAppMetrica
получите объект, который реализует протоколAppMetricaReporting
.Если репортер не был инициализирован с расширенной конфигурацией, то вызов данного метода произведет инициализацию репортера для указанного API key.
-
Используйте методы протокола
AppMetricaReporting
для отправки событий и Revenue. -
Чтобы сессии отслеживались правильно, настройте отправку событий о начале и приостановке сессии для каждого репортера.
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()
-
С помощью метода
+reporterForAPIKey:
классаAMAAppMetrica
получите объект, который реализует протоколAMAAppMetricaReporting
.Если репортер не был инициализирован с расширенной конфигурацией, то вызов данного метода произведет инициализацию репортера для указанного API key.
-
Используйте методы протокола
AMAAppMetricaReporting
для отправки событий и Revenue. -
Чтобы сессии отслеживались правильно, настройте отправку событий о начале и приостановке сессии для каждого репортера.
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 умеет определять местоположение устройства. Точность определения зависит от конфигурации, с которой инициализируется библиотека:
-
С включенной опцией
locationTracking
. Для iOS опция включена по умолчанию.Местоположение определяется с точностью до города. Информация доступна в отчетах и в Logs API.
Приложение запрашивает доступ к GPS. Расход заряда аккумулятора может увеличиться.
-
С отключенной опцией
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];
Не используйте переменные значения в качестве идентификатора для группировки. Иначе количество групп будет увеличиваться и их будет сложно анализировать.
Отправка ProfileId
Если отправка ProfileId
не настроена, в веб-интерфейсе будет отображаться appmetrica_device_id
.
Чтобы отправить ProfileId
, используйте свойство userProfileID
класса AppMetrica
.
AppMetrica.userProfileID = "id"
Чтобы отправить ProfileId
, используйте метод +setUserProfileID:
класса AMAAppMetrica
.
AMAAppMetrica.userProfileID = @"id";
Отправка атрибутов профиля
Чтобы отправить атрибуты профиля, передайте в метод 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);
}];
Отправка 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. Валидация позволяет фильтровать покупки, которые совершаются из взломанных приложений. Если валидация включена и покупка не проходит валидацию, она не отображается в отчетах.
Примечание
Чтобы покупки валидировались, включите валидацию в настройках.
Шаг 1. Протестируйте отправку Revenue
В AppMetrica нет возможности сегментировать Revenue на «тестовые» и «не тестовые». Если для отладки покупок вы используете основной API key, то тестовые покупки будут попадать в общую статистику. Поэтому, чтобы отладить отправку Revenue, используйте отправку статистики на дополнительный API key с помощью репортера.
Ниже описаны этапы отправки Revenue на дополнительный API key:
С валидацией
Чтобы покупки на iOS валидировались, в собственной реализации завершения транзакции настройте отправку поля transactionID
и receiptData
:
- Инициализируйте объект
MutableRevenueInfo
. - Для валидации покупки укажите
transactionID
иreceiptData
. Их необходимо получить до вызоваSKPaymentQueue.default().finishTransaction(transaction)
. - Отправьте объект
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)
}
- Инициализируйте объект
AMAMutableRevenueInfo
. - Для валидации покупки укажите
transactionID
иreceiptData
. Их необходимо получить до вызова[[SKPaymentQueue defaultQueue] finishTransaction:transaction]
. - Отправьте объект
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];
}
Без валидации
Чтобы отправить информацию о покупке без валидации:
-
Инициализируйте объект
MutableRevenueInfo
. -
(Опционально) Чтобы группировать покупки по
OrderID
, укажите его в свойствеpayload
.Примечание
Если идентификатор
OrderID
не указан, AppMetrica генерирует идентификатор автоматически. -
Отправьте объект
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)")
})
}
-
Инициализируйте объект
AMAMutableRevenueInfo
. -
(Опционально) Чтобы группировать покупки по
OrderID
, укажите его в свойствеpayload
.Примечание
Если идентификатор
OrderID
не указан, AppMetrica генерирует идентификатор автоматически. -
Отправьте объект
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);
}];
Отправка Ad Revenue
Шаг 1. Убедитесь, что SDK активирован
Пример активации:
let configuration = AppMetricaConfiguration.init(apiKey: "API key")
AppMetrica.activate(with: configuration!)
AMAAppMetricaConfiguration *configuration = [[AMAAppMetricaConfiguration alloc] initWithApiKey:@"API_key"];
[AMAAppMetrica activateWithConfiguration:configuration];
Шаг 2. Настройте отправку Ad Revenue
-
Импортируйте необходимые модули:
SwiftObjective-Cimport AppMetricaCore import AppLovinSDK
#import <AppMetricaCore/AppMetricaCore.h> #import <AppLovinSDK/AppLovinSDK.h>
-
Добавьте вспомогательное расширение для
MAAdFormat
:SwiftObjective-Cextension MAAdFormat { var appMetricaAdType: AdType { switch self { case .banner: return .banner case .interstitial: return .interstitial case .rewarded: return .rewarded case .native: return .native case .mrec: return .mrec default: return .other } } }
@implementation MAAdFormat (AppMetricaAdType) - (AdType)appMetricaAdType { switch (self) { case MAAdFormat.banner: return AdTypeBanner; case MAAdFormat.interstitial: return AdTypeInterstitial; case MAAdFormat.rewarded: return AdTypeRewarded; case MAAdFormat.native: return AdTypeNative; case MAAdFormat.mrec: return AdTypeMrec; default: return AdTypeOther; } } @end
-
Реализуйте
MAAdRevenueDelegate
:SwiftObjective-Cclass AdRevenueReporter: NSObject, MAAdRevenueDelegate { func didPayRevenue(for ad: MAAd) { // Create a MutableAdRevenueInfo object let adRevenueInfo = MutableAdRevenueInfo(adRevenue: NSDecimalNumber(value: ad.revenue), currency: "USD") // Set additional properties adRevenueInfo.adType = ad.format.appMetricaAdType adRevenueInfo.adNetwork = ad.networkName adRevenueInfo.adUnitID = ad.adUnitIdentifier adRevenueInfo.adPlacementName = ad.placement adRevenueInfo.precision = ad.revenuePrecision // Additional information can be added to payload if needed adRevenueInfo.payload = [ "adType": ad.format.label, "countryCode": ALSdk.shared().configuration.countryCode, "networkPlacement": ad.networkPlacement ] // Report the ad revenue to AppMetrica AppMetrica.reportAdRevenue(adRevenueInfo) } }
#import <AppMetricaCore/AppMetricaCore.h> #import <AppLovinSDK/AppLovinSDK.h>
-
Импортируйте необходимые модули:
SwiftObjective-Cimport AppMetricaCore import FairBidSDK
#import <AppMetricaCore/AppMetricaCore.h> #import <FairBidSDK/FairBidSDK.h>
-
Создайте функцию для отправки Ad Revenue в AppMetrica:
SwiftObjective-Cfunc reportToAppMetrica(_ impressionData: FYBImpressionData, placementId: String, adType: AdType) { let revenue = impressionData.netPayout.map { NSDecimalNumber(decimal: $0.decimalValue) } ?? .zero let currency = impressionData.currency ?? "USD" let adRevenueInfo = MutableAdRevenueInfo(adRevenue: revenue, currency: currency) adRevenueInfo.adType = adType adRevenueInfo.adNetwork = impressionData.demandSource adRevenueInfo.adUnitID = impressionData.creativeId adRevenueInfo.precision = impressionData.priceAccuracy.appMetricaPrecision AppMetrica.reportAdRevenue(adRevenueInfo) { error in print("Failed to report ad revenue to AppMetrica: \(error)") } }
void reportToAppMetrica(FYBImpressionData *impressionData, NSString *placementId, AdType adType) { NSDecimalNumber *revenue = impressionData.netPayout ? [[NSDecimalNumber alloc] initWithDecimal:impressionData.netPayout.decimalValue] : [NSDecimalNumber zero]; NSString *currency = impressionData.currency ? impressionData.currency : @"USD"; MutableAdRevenueInfo *adRevenueInfo = [[MutableAdRevenueInfo alloc] initWithAdRevenue:revenue currency:currency]; adRevenueInfo.adType = adType; adRevenueInfo.adNetwork = impressionData.demandSource; adRevenueInfo.adUnitID = impressionData.creativeId; adRevenueInfo.precision = [impressionData.priceAccuracy appMetricaPrecision]; [AppMetrica reportAdRevenue:adRevenueInfo completion:^(NSError *error) { if (error) { NSLog(@"Failed to report ad revenue to AppMetrica: %@", error); } }]; }
-
Добавьте расширение для преобразования формата цен Fyber в формат AppMetrica:
SwiftObjective-Cextension FYBImpressionDataPriceAccuracy { var appMetricaPrecision: String { switch self { case .undisclosed: return "undisclosed" case .predicted: return "predicted" case .programmatic: return "programmatic" @unknown default: return "unknown" } } }
@implementation NSNumber (FYBImpressionDataPriceAccuracyAppMetricaPrecision) + (NSString *)appMetricaPrecisionForFYBImpressionDataPriceAccuracy:(FYBImpressionDataPriceAccuracy)accuracy { switch (accuracy) { case FYBImpressionDataPriceAccuracyUndisclosed: return @"undisclosed"; case FYBImpressionDataPriceAccuracyPredicted: return @"predicted"; case FYBImpressionDataPriceAccuracyProgrammatic: return @"programmatic"; default: return @"unknown"; } } @end
-
Создайте функцию для отчета о показах OfferWall в AppMetrica:
SwiftObjective-Cfunc reportOfferWallShowToAppMetrica(placementId: String) { let adRevenueInfo = MutableAdRevenueInfo(adRevenue: NSDecimalNumber.zero, currency: "USD") adRevenueInfo.adType = .other adRevenueInfo.adUnitID = placementId AppMetrica.reportAdRevenue(adRevenueInfo) { error in print("Failed to report OfferWall show to AppMetrica: \(error)") } }
- (void)reportOfferWallShowToAppMetricaWithPlacementId:(NSString *)placementId { YMMMutableAdRevenueInfo *adRevenueInfo = [[YMMMutableAdRevenueInfo alloc] initWithAdRevenue:[NSDecimalNumber zero] currency:@"USD"]; adRevenueInfo.adType = YMMAdTypeOther; adRevenueInfo.adUnitID = placementId; [YMMYandexMetrica reportAdRevenueWithInfo:adRevenueInfo completionHandler:^(NSError * _Nullable error) { if (error) { NSLog(@"Failed to report OfferWall show to AppMetrica: %@", error); } }]; }
-
Создайте делегаты для каждого формата рекламы и соответствующие методы к ним:
SwiftObjective-Cclass YourBannerDelegate: NSObject, FYBBannerDelegate { func bannerDidShow(_ banner: FYBBannerAdView, impressionData: FYBImpressionData) { reportToAppMetrica(impressionData, placementId: banner.options.placementId, adType: .banner) } // Implement other delegate methods as needed } class YourInterstitialDelegate: NSObject, FYBInterstitialDelegate { func interstitialDidShow(_ placementId: String, impressionData: FYBImpressionData) { reportToAppMetrica(impressionData, placementId: placementId, adType: .interstitial) } // Implement other delegate methods as needed } class YourRewardedDelegate: NSObject, FYBRewardedDelegate { func rewardedDidShow(_ placementId: String, impressionData: FYBImpressionData) { reportToAppMetrica(impressionData, placementId: placementId, adType: .rewarded) } // Implement other delegate methods as needed } class YourOfferWallDelegate: NSObject, OfferWallDelegate { func didShow(_ placementId: String?) { reportOfferWallShowToAppMetrica(placementId: placementId ?? "unknown") } // Implement other delegate methods as needed }
// YourBannerDelegate @interface YourBannerDelegate : NSObject <FYBBannerDelegate> @end @implementation YourBannerDelegate - (void)bannerDidShow:(FYBBannerAdView *)banner impressionData:(FYBImpressionData *)impressionData { [self reportToAppMetricaWithImpressionData:impressionData placementId:banner.options.placementId adType:AdTypeBanner]; } // Implement other delegate methods as needed @end // YourInterstitialDelegate @interface YourInterstitialDelegate : NSObject <FYBInterstitialDelegate> @end @implementation YourInterstitialDelegate - (void)interstitialDidShowWithPlacementId:(NSString *)placementId impressionData:(FYBImpressionData *)impressionData { [self reportToAppMetricaWithImpressionData:impressionData placementId:placementId adType:AdTypeInterstitial]; } // Implement other delegate methods as needed @end // YourRewardedDelegate @interface YourRewardedDelegate : NSObject <FYBRewardedDelegate> @end @implementation YourRewardedDelegate - (void)rewardedDidShowWithPlacementId:(NSString *)placementId impressionData:(FYBImpressionData *)impressionData { [self reportToAppMetricaWithImpressionData:impressionData placementId:placementId adType:AdTypeRewarded]; } // Implement other delegate methods as needed @end // YourOfferWallDelegate @interface YourOfferWallDelegate : NSObject <OfferWallDelegate> @end @implementation YourOfferWallDelegate - (void)didShowWithPlacementId:(NSString *)placementId { // Assuming reportOfferWallShowToAppMetrica is implemented elsewhere [self reportOfferWallShowToAppMetricaWithPlacementId:placementId ? placementId : @"unknown"]; } // Implement other delegate methods as needed @end
-
Импортируйте необходимые модули:
SwiftObjective-Cimport AppMetricaCore import GoogleMobileAds
#import <AppMetricaCore/AppMetricaCore.h> #import <GoogleMobileAds/GoogleMobileAds.h>
-
Добавьте вспомогательное расширение для
GADAdValuePrecision
:SwiftObjective-Cextension GADAdValuePrecision: CustomStringConvertible { public var description: String { switch self { case .precise: return "precise" case .estimated: return "estimated" case .publisherProvided: return "publisher_defined" case .unknown: fallthrough @unknown default: return "unknown" } } }
@interface GADAdValuePrecisionHelper : NSObject + (NSString *)stringFromAdValuePrecision:(GADAdValuePrecision)precision; @end @implementation GADAdValuePrecisionHelper + (NSString *)stringFromAdValuePrecision:(GADAdValuePrecision)precision { switch (precision) { case GADAdValuePrecisionPrecise: return @"precise"; case GADAdValuePrecisionEstimated: return @"estimated"; case GADAdValuePrecisionPublisherProvided: return @"publisher_defined"; case GADAdValuePrecisionUnknown: default: return @"unknown"; } } @end
-
Реализуйте логику загрузки рекламы и создания отчетов о показах:
SwiftObjective-Cclass ViewController: UIViewController, GADFullScreenContentDelegate { var rewardedAd: GADRewardedAd? func requestRewardedAd() { GADRewardedAd.load( withAdUnitID: "AD_UNIT_ID", request: GADRequest() ) { [weak self] (ad, error) in if let error = error { print("Rewarded ad failed to load with error: \(error.localizedDescription)") return } if let ad = ad { self?.rewardedAd = ad self?.rewardedAd?.paidEventHandler = { adValue in // Extract the impression-level ad revenue data let value = adValue.value let precision = adValue.precision let currencyCode = adValue.currencyCode // Get the ad unit ID let adUnitId = ad.adUnitID // Get additional response info let responseInfo = ad.responseInfo let loadedAdNetworkResponseInfo = responseInfo.loadedAdNetworkResponseInfo let adSourceId = loadedAdNetworkResponseInfo?.adSourceID let adSourceInstanceId = loadedAdNetworkResponseInfo?.adSourceInstanceID let adSourceInstanceName = loadedAdNetworkResponseInfo?.adSourceInstanceName let adSourceName = loadedAdNetworkResponseInfo?.adSourceName let mediationGroupName = responseInfo.extrasDictionary["mediation_group_name"] as? String let mediationABTestName = responseInfo.extrasDictionary["mediation_ab_test_name"] as? String let mediationABTestVariant = responseInfo.extrasDictionary["mediation_ab_test_variant"] as? String // Create AdRevenueInfo object let adRevenueInfo = MutableAdRevenueInfo(adRevenue: value, currency: currencyCode) adRevenueInfo.adType = .rewarded adRevenueInfo.adNetwork = adSourceName ?? "AdMob" adRevenueInfo.adUnitID = adUnitId adRevenueInfo.adPlacementID = adSourceId adRevenueInfo.precision = precision.description // Create payload with additional information var payload: [String: String] = [:] if let adSourceInstanceId = adSourceInstanceId { payload["ad_source_instance_id"] = adSourceInstanceId } if let adSourceInstanceName = adSourceInstanceName { payload["ad_source_instance_name"] = adSourceInstanceName } if let mediationGroupName = mediationGroupName { payload["mediation_group_name"] = mediationGroupName } if let mediationABTestName = mediationABTestName { payload["mediation_ab_test_name"] = mediationABTestName } if let mediationABTestVariant = mediationABTestVariant { payload["mediation_ab_test_variant"] = mediationABTestVariant } adRevenueInfo.payload = payload // Report to AppMetrica AppMetrica.reportAdRevenue(adRevenueInfo) { error in print("Failed to report ad revenue: \(error)") } } } } } }
@interface ViewController : UIViewController <GADFullScreenContentDelegate> @property (nonatomic, strong) GADRewardedAd *rewardedAd; @end @implementation ViewController - (void)requestRewardedAd { [GADRewardedAd loadWithAdUnitID:@"AD_UNIT_ID" request:[GADRequest request] completionHandler:^(GADRewardedAd * _Nullable rewardedAd, NSError * _Nullable error) { if (error) { NSLog(@"Rewarded ad failed to load with error: %@", [error localizedDescription]); return; } self.rewardedAd = rewardedAd; __weak typeof(self) weakSelf = self; // Avoid strong reference cycles self.rewardedAd.paidEventHandler = ^(GADAdValue *adValue) { // Extract the impression-level ad revenue data NSDecimalNumber *value = adValue.value; GADAdValuePrecision precision = adValue.precision; NSString *currencyCode = adValue.currencyCode; // Get the ad unit ID NSString *adUnitId = weakSelf.rewardedAd.adUnitID; // Create AdRevenueInfo object YMMMutableAdRevenueInfo *adRevenueInfo = [[YMMMutableAdRevenueInfo alloc] initWithAdRevenue:value.doubleValue currency:currencyCode]; adRevenueInfo.adType = YMMAdTypeRewarded; adRevenueInfo.adNetwork = @"AdMob"; adRevenueInfo.adUnitID = adUnitId; adRevenueInfo.precision = [NSString stringWithFormat:@"%ld", (long)precision]; // Report to AppMetrica [YMMYandexMetrica reportAdRevenue:adRevenueInfo onFailure:^(NSError *error) { NSLog(@"Failed to report ad revenue: %@", error); }]; }; }]; } @end
Адаптируйте реализацию для других рекламных форматов
-
Замените
GADRewardedAd
соответствующим классом:- Banner:
GADBannerView
- Interstitial:
GADInterstitialAd
- Rewarded interstitial:
GADRewardedInterstitialAd
- Native:
GADNativeAd
- Banner:
-
Измените
adType
при создании объектаAdRevenueInfo
:SwiftObjective-CadRevenueInfo.adType = .banner // For banner ads adRevenueInfo.adType = .interstitial // For interstitial and rewarded interstitial ads adRevenueInfo.adType = .native // For native ads adRevenueInfo.adType = .rewarded // For rewarded ads (current example)
// For banner ads adRevenueInfo.adType = AdTypeBanner; // For interstitial and rewarded interstitial ads adRevenueInfo.adType = AdTypeInterstitial; // For native ads adRevenueInfo.adType = AdTypeNative; // For rewarded ads (current example) adRevenueInfo.adType = AdTypeRewarded;
-
Настройте обработчик
paidEventHandler
на соответствующем этапе процесса загрузки рекламы для каждого формата. Реализация самого обработчика остается прежней. -
Для баннерной рекламы установите обработчик
paidEventHandler
непосредственно в экземпляреGADBannerView
:SwiftObjective-CbannerView.paidEventHandler = { adValue in // Use the same implementation as in the rewarded ad example }
bannerView.paidEventHandler = ^(GADAdValue *adValue) { // Use the same implementation as in the rewarded ad example };
-
Для Interstitial, Rewarded interstitial и Native, установите обработчик
paidEventHandler
в обработчике завершения загрузки рекламы, как в примере с Rewarded.
Примечание
Не забудьте заменить AD_UNIT_ID
на ваш реальный идентификатор рекламного блока AdMob для каждого используемого формата рекламы.
Данные о доходах от рекламы из ironSource SDK в AppMetrica передаются с помощью AppMetricaIronSourceAdapter
:
- Адаптер должен быть инициализирован до активации ironSource.
- Порядок, в котором активируются AppMetrica и адаптер, не имеет значения, но AppMetrica следует активировать только один раз в течение жизненного цикла приложения.
-
Импортируйте необходимые модули:
SwiftObjective-Cimport AppMetricaCore import AppMetricaIronSourceAdapter import IronSource
#import <AppMetricaCore/AppMetricaCore.h> #import <AppMetricaIronSourceAdapter/AppMetricaIronSourceAdapter.h> import <IronSource/IronSource.h>
-
Инициализируйте
AppMetricaIronSourceAdapter
перед активацией ironSource. Обычно это можно сделать в коде инициализации вашего приложения, например, в структуреAppDelegate
илиmain App
для приложенийSwiftUI
.SwiftObjective-CAppMetricaIronSourceAdapter.shared.initialize()
[[AppMetricaIronSourceAdapter shared] initialize];
-
Настройте и активируйте ironSource и AppMetrica:
SwiftObjective-C// Initialize IronSource IronSource.initWithAppKey("YOUR_IRONSOURCE_APP_KEY", adUnits: [IS_BANNER, IS_INTERSTITIAL, IS_REWARDED_VIDEO]) // Activate AppMetrica guard let configuration = AppMetricaConfiguration(apiKey: "YOUR_APPMETRICA_API_KEY") else { return } AppMetrica.activate(with: configuration)
// Initialize IronSource [IronSource initWithAppKey:@"YOUR_IRONSOURCE_APP_KEY" adUnits:@[IS_BANNER, IS_INTERSTITIAL, IS_REWARDED_VIDEO]]; // Activate AppMetrica AppMetricaConfiguration *configuration = [[AppMetricaConfiguration alloc] initWithApiKey:@"YOUR_APPMETRICA_API_KEY"]; if (configuration == nil) { return; } [AppMetrica activateWithConfiguration:configuration];
Примечание
AppMetricaIronSourceAdapter
автоматически передает данные о доходах от рекламы из ironSource в AppMetrica. Вам не нужно вручную сообщать о показах или доходах.
-
Импортируйте необходимые модули:
SwiftObjective-Cimport AppMetricaCore import AnyThinkSDK import AnyThinkBanner import AnyThinkNative import AnyThinkInterstitial import AnyThinkRewardedVideo import AnyThinkMediaVideo
#import <AppMetricaCore/AppMetricaCore.h> #import <AnyThinkSDK/AnyThinkSDK.h> import <AnyThinkBanner/AnyThinkBanner.h> import <AnyThinkNative/AnyThinkNative.h> import <AnyThinkInterstitial/AnyThinkInterstitial.h> import <AnyThinkRewardedVideo/AnyThinkRewardedVideo.h> import <AnyThinkMediaVideo/AnyThinkMediaVideo.h>
-
Создайте функцию для отправки Ad Revenue в AppMetrica:
SwiftObjective-Cfunc reportToAppMetrica(_ extra: [AnyHashable: Any], placementID: String, adType: AdType) { guard let revenue = extra[kATADDelegateExtraPublisherRevenueKey] as? Double, let currency = extra[kATADDelegateExtraCurrencyKey] as? String else { print("Missing required revenue information") return } let adRevenueInfo = MutableAdRevenueInfo(adRevenue: NSDecimalNumber(value: revenue), currency: currency) adRevenueInfo.adType = adType adRevenueInfo.adNetwork = extra[kATADDelegateExtraNetworkNameKey] as? String adRevenueInfo.adUnitID = extra[kATADDelegateExtraAdunitIDKey] as? String adRevenueInfo.adPlacementID = placementID adRevenueInfo.precision = extra[kATADDelegateExtraPrecisionKey] as? String // Additional information in payload var payload: [String: String] = [:] if let networkFirmId = extra[kATADDelegateExtraNetworkFirmIdKey] as? Int { payload["network_firm_id"] = String(networkFirmId) } payload["adsource_id"] = extra[kATADDelegateExtraAdSourceIdKey] as? String // Add other relevant information to payload... adRevenueInfo.payload = payload AppMetrica.reportAdRevenue(adRevenueInfo) { error in print("Failed to report ad revenue to AppMetrica: \(error)") } }
- (void)reportToAppMetricaWithExtra:(NSDictionary<AnyHashable, id> *)extra placementID:(NSString *)placementID adType:(AdType)adType { NSNumber *revenue = extra[kATADDelegateExtraPublisherRevenueKey]; NSString *currency = extra[kATADDelegateExtraCurrencyKey]; if (revenue == nil || currency == nil) { NSLog(@"Missing required revenue information"); return; } MutableAdRevenueInfo *adRevenueInfo = [[MutableAdRevenueInfo alloc] initWithAdRevenue:[NSDecimalNumber decimalNumberWithDecimal:[revenue decimalValue]] currency:currency]; adRevenueInfo.adType = adType; adRevenueInfo.adNetwork = extra[kATADDelegateExtraNetworkNameKey]; adRevenueInfo.adUnitID = extra[kATADDelegateExtraAdunitIDKey]; adRevenueInfo.adPlacementID = placementID; adRevenueInfo.precision = extra[kATADDelegateExtraPrecisionKey]; // Additional information in payload NSMutableDictionary<NSString *, NSString *> *payload = [NSMutableDictionary new]; NSNumber *networkFirmId = extra[kATADDelegateExtraNetworkFirmIdKey]; if (networkFirmId != nil) { payload[@"network_firm_id"] = [networkFirmId stringValue]; } payload[@"adsource_id"] = extra[kATADDelegateExtraAdSourceIdKey]; // Add other relevant information to payload... adRevenueInfo.payload = payload; [AppMetrica reportAdRevenue:adRevenueInfo completion:^(NSError * _Nullable error) { if (error) { NSLog(@"Failed to report ad revenue to AppMetrica: %@", error); } }]; }
-
Имплементируйте соответствующие методы делегата для каждого формата рекламы:
SwiftObjective-Cclass YourBannerDelegate: NSObject, ATBannerDelegate { func bannerView(_ bannerView: ATBannerView, didShowAdWithPlacementID placementID: String, extra: [AnyHashable : Any]) { reportToAppMetrica(extra, placementID: placementID, adType: .banner) } // Implement other delegate methods as needed } class YourNativeDelegate: NSObject, ATNativeADDelegate { func didShowNativeAd(in adView: ATNativeADView, placementID: String, extra: [AnyHashable : Any]) { reportToAppMetrica(extra, placementID: placementID, adType: .native) } // Implement other delegate methods as needed } class YourInterstitialDelegate: NSObject, ATInterstitialDelegate { func interstitialDidShow(forPlacementID placementID: String, extra: [AnyHashable : Any]) { reportToAppMetrica(extra, placementID: placementID, adType: .interstitial) } // Implement other delegate methods as needed } class YourRewardedVideoDelegate: NSObject, ATRewardedVideoDelegate { func rewardedVideoDidShow(forPlacementID placementID: String, extra: [AnyHashable : Any]) { reportToAppMetrica(extra, placementID: placementID, adType: .rewarded) } // Implement other delegate methods as needed } class YourSplashDelegate: NSObject, ATSplashDelegate { func splashDidShow(forPlacementID placementID: String, extra: [AnyHashable : Any]) { reportToAppMetrica(extra, placementID: placementID, adType: .other) } // Implement other delegate methods as needed } class YourMediaVideoDelegate: NSObject, ATMediaVideoDelegate { func mediaVideoDidStartPlaying(forPlacementID placementID: String, extra: [AnyHashable : Any]) { reportToAppMetrica(extra, placementID: placementID, adType: .other) media video } // Implement other delegate methods as needed }
#import <AppMetricaCore/AppMetricaCore.h> #import <AnyThinkSDK/AnyThinkSDK.h> import <AnyThinkBanner/AnyThinkBanner.h> import <AnyThinkNative/AnyThinkNative.h> import <AnyThinkInterstitial/AnyThinkInterstitial.h> import <AnyThinkRewardedVideo/AnyThinkRewardedVideo.h> import <AnyThinkMediaVideo/AnyThinkMediaVideo.h>
-
Инициализируйте объект
MutableAdRevenueInfo
. -
Отправьте объект
MutableAdRevenueInfo
на основной API key с помощью метода+reportAdRevenue:onFailure:
классаAppMetrica
.SwiftObjective-CAppMetrica.report(adRevenue: adRevenueInfo) { error in print("AdRevenue error: \(error)") }
[AMAAppMetrica reportAdRevenue:[adRevenueInfo copy] onFailure:^(NSError *error) { NSLog(@"AdRevenue error: %@", error); }];
Шаг 3. Убедитесь, что Ad Revenue отображается в отчетах
-
Совершите просмотры рекламы в приложении.
-
Убедитесь, что в отчете Revenue количество событий Ad Revenue соответствует количеству просмотров рекламы.
Установка длительности тайм-аута сессии
По умолчанию длительность таймаута сессии равна 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];
Отслеживание открытий приложения с помощью deeplink
Важно
Начиная с версии AppMetrica SDK iOS 4.0, отслеживание открытия приложения через deeplink работает автоматически. Для остальных вариантов настройте отслеживание вручную:
Отслеживание открытий необходимо для корректного трекинга ремаркетинг-кампаний.
Примечание
Для работы с 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.
Учет новых пользователей
По умолчанию в момент первого запуска приложения все пользователи определяются как новые. Если 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)")
}
}
}
Если вы не нашли ответ на свой вопрос, то вы можете задать его через форму обратной связи. Пожалуйста, опишите возникшую проблему как можно подробнее. Если возможно, приложите скриншот.
Рекламная кампания, которая направлена на возвращение пользователей в установленное приложение. Подробнее о создании ремаркетинг-кампании в разделе Создание ремаркетинг-трекера.