Базовый модуль🔗
Помимо инициализации и сбора статистики, с помощью базового модуля вы также можете получить информацию об устройстве, открыть настройки вашего приложения, показать запрос на разрешение трекинга (IDFA) на iOS 14+, и многое другое. Читайте о возможностях ниже.
Запрос разрешения на трекинг пользователя на iOS 14+🔗
Рекламный идентификатор (IDFA) на iOS позволяет идентифицировать устройство пользователя и отслеживать его активность. Под отслеживанием понимается процесс связывания данных пользователей и устройств, собранных из вашего приложения, с данными, собранными из приложений, веб-сайтов или ресурсов других компаний. Это необходимо для атрибуции трафика и отслеживания конверсий (установок, покупок и т.д.). До iOS 14 пользователь мог на уровне системы ограничить передачу IDFA во все приложения, но это делала малая часть игроков, поэтому мы могли отслеживать большинство. В iOS 14 Apple добавила новый тип разрешений - разрешение на трекинг пользователя, до iOS 14.5 оно необязательно, но начиная с iOS 14.5, чтобы получить IDFA приложение обязано показать пользователю «запрос на отслеживание», и только если пользователь согласился, мы получим IDFA. Подробнее про отслеживание и его примеры можно почитать в официальной документации. С официальной документацией по библиотеке AppTrackingTransparency (ATT) можно ознакомиться здесь
Несколько важных моментов про показ запроса:
- Запрос будет показан единожды, вне зависимости от того, сколько раз приложение вызывает метод показа. Поменять свое решение пользователь может только в настройках системы.
- Пользователь может как и до iOS 14 ограничить отдачу IDFA приложениям глобально, в таком случае окно запроса даже не покажется. Оно будет показано только когда пользователь изменит данную глобальную настройку.
- Запрос можно показать в любой момент работы приложения, не обязательно на старте. Apple рекомендует показывать запрос прямо перед тем, как IDFA действительно понадобится, например, перед показом рекламы, чтобы пользователь понимал, зачем это нужно.
- При показе запроса необходимо предоставить строку с описанием/объяснением того, зачем вам нужно отслеживать пользователя. Она указывается в Info.plist приложения, ее можно локализовать.
- Запрос влияет только на отдачу IDFA, IDFV будет отдаваться как и раньше

Ниже приведено описание внедрения запроса в ваше приложение:
Шаг 1. Добавление описания🔗
Для того, чтобы показать данный запрос в первую очередь нужно добавить поле NSUserTrackingUsageDescription с описанием того, зачем вам необходимо отслеживать пользователя, в Info.plist приложения. Для этого:
Добавьте следующий код в PostProcessBuild:
public class MRGSPostBuildProcessSample
{
[PostProcessBuild]
public static void PostProcessBuild(BuildTarget target, string path)
{
string plistPath = path + "/Info.plist";
PlistDocument plist = new PlistDocument();
plist.ReadFromString(File.ReadAllText(plistPath));
PlistElementDict rootDict = plist.root;
// Adding descriptions
rootDict.SetString("NSUserTrackingUsageDescription",
"This identifier will be used to deliver personalized ads to you.");
}
}
Добавьте следующий код в UPL file:
Локализация запроса
Одна из студий сделала скрипт локализации для Unity, исходный код можно скачать по ссылкам: IosPostBuildProcessor и BuildSettingsConfig
Про локализацию ресурсов в iOS можно почитать по ссылке. Чтобы локализовать их из Unity, нужно копировать в PostBuild в собранный проект XCode уже подготовленные файлы локализации, пример можно найти здесь.
При локализации из Unity могут быть небольшие проблемы с тем, что это "нативная" локализация, а не Unity, поэтому надо у проекта будет выставлять поддерживаемые локализации. Если у вас возникли такие проблемы - можете обратиться к странице MRGSGameCenter, к разделу "Что делать, если возникли проблемы с локализацией на iOS?"
Шаг 2. Проверка необходимости показа🔗
Затем, нужно определить, в какой момент вы хотите показывать данное окно пользователю. Мы рекомендуем показывать окно прямо перед показом рекламы, предварительно рассказав пользователю о том, зачем необходимо данное разрешение. Для проверки необходимости показа диалога запроса разрешения на трекинг у пользователя воспользуйтесь методом:
С помощью него вы можете понять, нужно ли, например, показать предварительный диалог с объяснением того, зачем это нужно, гарантированно зная, что потом запрос будет показан. Рекомендуем всегда перед вызовом метода requestTrackingAuthorizationWithCompletionHandler проверять результат работы данного метода. На версиях до iOS 14 всегда будет возвращен false. На версиях iOS 14 будет возвращен true, если диалог еще не разу не был показан пользователю и false в случаях, когда пользователь видел диалог, или запретил трекинг в настройках.
Важное исключение
На ранних версиях iOS 14 IDFA приходит без запроса разрешения. Диалог в таком случае покажется (если вызвать метод показа), но если мы уже получаем IDFA, то его показывать нет смысла. Поэтому, в случаях, когда IDFA уже получен данный метод вернет false (Для того, чтобы вы могли протестировать поведение метода, такой механизм будет работать только в случае, если при инициализации MRGS флаг showTrackingAuthorizationDialogOnAlliOSVersions выставлен в false.)
Шаг 3. Показ запроса🔗
Для показа окна запроса разрешения на трекинг у пользователя воспользуйтесь методом:
// public void RequestTrackingAuthorization(Action<MRGSIDFATrackingAuthorizationStatus> completion);
MRGSDevice.Instance.RequestTrackingAuthorization((MRGSIDFATrackingAuthorizationStatus status) => {
// Handle the result
});
Возможные статусы:
public enum MRGSIDFATrackingAuthorizationStatus
{
/// Request window wasn't shown to user at all
NotDetermined = 0,
/// User switched off tracking in device settings
Restricted = 1,
/// User asked app not to track in request window (or later in device settings)
Denied = 2,
/// User has granted permission to track
Authorized = 3,
}
#include "MRGSDevice.h"
FMRGSDevice::Get().RequestTrackingAuthorization([](EMRGSIDFATrackingAuthorizationStatus Status) {
// Handle the result
});
Возможные статусы:
/**
* Describe the status of the user's tracking permission request (IDFA request on iOS 14+).
*/
enum MRGSERVICE_API EMRGSIDFATrackingAuthorizationStatus
{
/**
* Request window was not shown to user at all.
*/
NotDetermined = 0,
/**
* User switched off tracking in device settings.
*/
Restricted = 1,
/**
* User asked app not to track in request window (or later in device settings).
*/
Denied = 2,
/**
* User has granted permission to track.
*/
Authorized = 3
};
// - (void)requestTrackingAuthorizationWithCompletionHandler:(void (^)(MRGSIDFATrackingAuthorizationStatus status))completion;
[[MRGSDevice currentDevice] requestTrackingAuthorizationWithCompletionHandler:^(MRGSIDFATrackingAuthorizationStatus status) {
// Process result
}];
Возможные статусы:
typedef NS_ENUM(NSUInteger, MRGSIDFATrackingAuthorizationStatus) {
/// Request window wasn't shown to user at all
MRGSIDFATrackingAuthorizationStatusNotDetermined = 0,
/// User switched off tracking in device settings
MRGSIDFATrackingAuthorizationStatusRestricted,
/// User asked app not to track in request window (or later in device settings)
MRGSIDFATrackingAuthorizationStatusDenied,
/// User has granted permission to track
MRGSIDFATrackingAuthorizationStatusAuthorized
};
Данное окно показывается только на iOS 14+, на остальных версиях сразу вернется статус Authorized или Restricted, в зависимости от настроек пользователя. Вне зависимости ит количества вызовов, окно показывается только один раз, потом будет просто возвращен текущий статус.
Статистика
При использовании наших методов, MRGS автоматически собирает статистику по показам/соглашениям/отказам с помощью MRGSMetrics (метрика -16)
Получение текущего статуса🔗
Для того, чтобы узнать текущий статус разрешения трекинга MRGSIDFATrackingAuthorizationStatus, воспользуйтесь свойством (На версиях до iOS 14 будет возвращаться статус Authorized или Restricted, в зависимости от настроек пользователя):
Переход в настройки
Если пользователь уже отказался от трекинга в системном окне, но готов включить его обратно, то вы можете перебросить его прямо в приложение настроек на вкладку вашего приложения с помощью данного метода
Автоматический показ🔗
В случае, если вы хотите показывать окно с запросом разрешения пользователю сразу при старте, то установите соответствующий флаг в настройках MRGS ( в таком случае методы, описанные выше, можно не вызывать):
Получение статуса согласия пользователя на отслеживание с учетом IDFA🔗
Поскольку мы можем показывать запрос разрешения на трекинг не всем пользователям, а только с iOS 14.5+, то для получения текущего статуса согласия удобнее воспользоваться методом: (проверяет наличие IDFA. Если он выдан системой - значит пользователя согласился на отслеживание)
Важное обобщение
Мы сделали гибкий API, чтобы игры могли сами выбирать, что и как они должны показывать. Но наш основной подход - это сначала проверка необходимости показа, и показ. Метод для проверки необходимости показа проверяет не только то, был ли ранее показан диалог, но и то, получен ли уже IDFA, и если он получен, то показывать не нужно(такова логика нашего метода), чтобы игры могли заранее внедрить эту данную систему, а как только выйдет iOS с обязательным требованием показа запроса (iOS 14.5), то у игр автоматом стали бы появляться окна с запросом. То есть они были бы подготовлены, и когда действительно надо показать - показ был, а на версиях iOS 14, где IDFA и так отдается сам - не показывать(лишний раз не получать отказ). Соответственно с флагом showTrackingAuthorizationDialogOnAlliOSVersions, мы в методе проверки необходимости показа не смотрим на полученный IDFA, чтоб игры могли как то протестировать этот механизм. Это наш заложенный подход.
Но также игры могут сами в любой момент вызывать метод показа окна, и оно покажется (не вызывая наш метод проверки необходимости), а также получить текущий статус, и тд. То есть уже игра сама выбирает, как она хочет показывать этот диалог, хочет показывать на версиях до iOS 14.5 - можно вызвать метод показа.
Открытие настроек приложения🔗
Если вы хотите перенаправить пользователя в системные настройки в раздел настроек вашего приложения (пользователь сразу попадет в место, где сможет быстро изменить настройки уведомлений, геопозиции, трекинга(IDFA на iOS 14+), и другого), воспользуйтесь методом:
Открытие системного окна "Поделиться"🔗
MRGS позволяет показать системное окно шеринга данных (share button), а также окно отправки email (на iOS при выборе email будет показано отдельное окно составления письма)

Поддерживаемые типы данных:
- Текст/тема
- Заголовок (только для Android)
- Ссылки
- Изображения
- Файлы
Сначала необходимо настроить данные, которыми необходимо поделиться (или отправить письмо), а затем вызвать метод показа и передать туда настроенный ранее объект. Объект результата вернется в хендлер:
// Setting options
var options = new MRGSShareOptions()
{
Text = "Hello from MRGS!",
Subject = "MRGS Sample App",
Title = "MRGS Share Title",
Url = "https://mrgs.astrum.team",
EmailRecipients = new List<string>{"games.services@my.games"}
};
var image = new Texture2D(128, 128);
options.AddImage(image);
var soundFilePath = System.IO.Directory.GetParent(Application.dataPath) + "/" + "CustomNotificationSound.caf";
options.AddFile(soundFilePath);
// Show dialog
MRGSApplication.Instance.Share(options, (result, error) =>
{
Debug.Log("MRGSApplication#Share Result - " + result + ". Error - " + error);
});
// Setting options
MRGSShareOptions* options = [[MRGSShareOptions alloc] init];
options.text = @"Hello from MRGS!";
options.subject = @"MRGS Sample App";
options.url = @"https://mrgs.astrum.team";
[options addImage:[UIImage imageNamed:@"MRGSLogo"] withName:@"Logo.png"];
[options addFile:[[NSBundle mainBundle] URLForResource:@"custom_coppa_birthday" withExtension:@"html"].path];
options.emailRecipients = @[@"games.services@my.games"];
// Show dialog
[[MRGSApplication currentApplication] share:options completionHandler:^(MRGSShareResult * _Nullable result, NSError * _Nullable error) {
NSLog(@"Received share result - %@", result);
}];
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.File;
import java.util.Collections;
import games.my.mrgs.MRGSApplication;
import games.my.mrgs.MRGSError;
import games.my.mrgs.MRGSShareOptions;
import games.my.mrgs.MRGSShareResult;
import games.my.mrgs.utils.optional.BiConsumer;
// Setting options
final File imageFile = new File("path_to_my_image");
final MRGSShareOptions shareOptions = MRGSShareOptions.newBuilder()
.setTitle("MRGS Share Title")
.setSubject("MRGS Subject")
.setText("Some text for image")
.setFiles(Collections.singletonList(imageFile.getPath()))
.setEmailRecipients(Collections.singletonList("test@test.test"))
.build();
// Show dialog
MRGSApplication.getInstance().share(context, shareOptions, new BiConsumer<MRGSShareResult, MRGSError>()
{
@Override
public void accept(@NonNull MRGSShareResult result, @Nullable MRGSError error) {
// Handle result here.
}
});
Особенности share поведения
Некоторыми типами данных, например ссылки/изображения/файлы лучше делиться по отдельности для более понятного для пользователя отображения UI. На iOS, также, не все приложения могут принимать массив с объектами, которыми поделился пользователь (например, если поделиться текстом и ссылкой, то действие "копировать" заберет только ссылку, а если выбрать отправку по почте, то в письме будет и текст и ссылка, то есть в некоторых случаях лучше текст и ссылку передавать как одну строку в поле text)
Управление постбеками конверсий SKAdNetwork🔗
Начиная с выхода iOS 14.5 Apple внедряет новую политику использования IDFA (ATT), теперь приложение должно явно запросить у пользователя доступ к данному идентификатору, оценка на пользователей, которые позволят его использовать колеблется около 10-20%. В связи с этим для существенной доли аудитории теряется возможность следить за атрибуцией отдельных пользователей по старым схемам.
На замену Apple предложила свое решение - SKAdNetwork, позволяющее "связать" установки на устройстве пользователя без необходимости отправлять рекламный идентификатор на сервера. Apple с помощью SKAdNetwork сам осуществляет атрибуцию и позволяет получить рекламной сети обезличенный постбек после установки. Сеть может понять что конверсия (постбек) осуществилась по какой-то кампании, но не будет знать по какому пользователю.

MRGS позволяет проектам:
- гибко настроить правила расчета и установки conversionValue, при чем настройка, включение происходит удаленно на сервере, без обновления клиента;
- выставить conversionValue;
- собрать статистику.
Подробнее про работу с SKAdNetwork читайте на отдельной странице
Получение разных данных об устройстве, сервере, и другое🔗
Информация об устройстве🔗
С помощью класса MRGSDevice вы можете получить следующие данные об устройстве:
// Getting the device locale
string MRGSDevice.Instance.Country;
// Get the device name
string MRGSDevice.Instance.Model;
// Get platform name
string MRGSDevice.Instance.Platform;
// If the device is jailbroken (worth a jailbreak), then true will return.
bool MRGSDevice.Instance.HasJailbreak;
// Convert SystemLanguage to ISO 639-1 format ("german" -> "de").
string MRGSUtils.SystemLanguageToISO(SystemLanguage language);
// Getting the device locale
FString FMRGSDevice::Get().GetCountry();
// Get the device name
FString FMRGSDevice::Get().GetDeviceModel();
// Get platform name
FString FMRGSDevice::Get().GetPlatform();
// If the device is jailbroken (worth a jailbreak), then true will return.
bool FMRGSDevice::Get().HasJailbreak();
// Getting the device locale
+ (NSString*)country;
// String representation of the device name
@property (nonatomic, readonly, copy) NSString* model;
// Get platform name
@property (nonatomic, readonly, copy) NSString* platform;
// If the device is jailbroken (worth a jailbreak), then true will return.
- (BOOL)isDeviceJailbreak;
Note
На нативных платформах параметров для получения еще больше, поэтому смотрите в заголовочные файлы нативных классов.
А также получить уникальный идентификатор устройства, который использует MRGS:
Получение идентификаторов IDFA/IDFV🔗
Чтобы получить рекламный идентификатор устройства (IDFA) или идентификатор для издателя (IDFV. Только на iOS), воспользуйтесь полями:
// IDFA synchronous way
MRGSDevice.Instance.AdvertisingIdentifier;
// Asynchronous way
// Return IDFA for Apple store, GAID for Amazon, Google and Samsung stores, OAID for Huawei store,
// or null for other stores.
MRGSDevice.Instance.GetIdentifierForAdvertising(Action<string, MRGSError>);
// Async/await way
var (id, error) = await MRGSDevice.Instance.GetIdentifierForAdvertisingAsync();
var id = await MRGSDevice.Instance.GetIdentifierForAdvertisingAsync().Throwable();
// IDFV only iOS
MRGSDevice.Instance.IdentifierForVendor;
// Return IDFV for Appse store, AppSet id for Google store, ODID for Huawei store or null for other stores.
MRGSDevice.Instance.GetIdentifierForVendor(Action<string, MRGSError>);
// Async/await way
var (id, error) = await MRGSDevice.Instance.GetIdentifierForVendorAsync();
var id = await MRGSDevice.Instance.GetIdentifierForVendorAsync().Throwable();
// Return IDFA for Apple store, GAID for Amazon, Google and Samsung stores, OAID for Huawei store,
// or null for other stores.
FMRGSDevice::Get().GetAdvertisingId(TFunction<void(FAdvertisingIdPtr, FErrorPtr)>);
// Return IDFV for Appse store, AppSet id for Google store, ODID for Huawei store or null for other stores.
FMRGSDevice::Get().GetVendorId(TFunction<void(FAdvertisingIdPtr, FErrorPtr)>);
// IDFA
// Return an advertising identifier (GAID for Amazon, Google, Samsung stores
// or OAID for Huawei store). For other storages will return null.
MRGSDevice.getInstance().getAdvertisingId(Context, AdvertisingIdCallback);
// Return AppSet id for Google store, ODID for Huawei store or null for other stores.
MRGSDevice.getInstance().getVendorId(Context, OnVendorIdCallback);
Информация о приложении🔗
Также вы можете получить данные о серверном времени, и URL, с которым было запущено приложение:
Серверное время🔗
MRGS позволяет Вам получить актуальное серверное время в любой момент работы приложения.
Причины из-за которых вернулось серверное время 0
- Самый первый запуск приложения, так как чтобы серверное время было отличное от 0, нужно чтобы выполнился хотя бы один сетевой запрос на сервер MRGS.
- iOS кэширует серверное время в файловую систему после его первого получения. Но если устройство будет перезагружено или пользователь вручную переведет время на устройстве(и перезагрузит приложение), то серверное время может придти 0, если обращение будет сделано до того как придет сетевой ответ от сервера
- Android хранит серверное время только на время сессии, потому при любом первом запуске приложения может прийти 0, если обращение будет сделано до того как придет сетевой ответ от сервера.
Замечание
Обратите внимание, что время пересчитывается каждый раз когда приходит сетевой ответ от сервера. Из-за того что сервер кэширует время и обновляет его раз в минуту, можно наблюдать некоторые "скачки времени", когда время сбрасывается на несколько секунд до 1 минуты назад.
Географическое положение по IP🔗
MRGS позволяет вам получить географическое положение устройства с доступом в Интернет по его IP-адресу. Результат запроса возвращается в формате двухбуквенного кода страны по стандарту ISO 3166-1 alpha-2.
// Callback way
MRGSDevice.Instance.GetGeoIpInfo((geoIpInfo, error) => {
if (geoIpInfo != null)
{
Debug.Log("MRGSDevice - MRGSGeoIpInfo success: " + geoIpInfo);
}
else
{
Debug.Log("MRGSDevice - MRGSGeoIpInfo failed: " + error);
}
});
// Async/await way
var (geoIpInfo, error) = await MRGSDevice.Instance.GetGeoIpInfoAsync();
// or with throw Exception
var geoIpInfo = await MRGSDevice.Instance.GetGeoIpInfoAsync().Throwable();
import android.util.Log;
import androidx.annotation.Nullable;
import games.my.mrgs.MRGSDevice;
import games.my.mrgs.MRGSError;
import games.my.mrgs.MRGSGeoIpInfo;
import games.my.mrgs.utils.optional.BiConsumer;
MRGSDevice.getInstance().getGeoIpInfo(new BiConsumer<MRGSGeoIpInfo, MRGSError>() {
@Override
public void accept(@Nullable MRGSGeoIpInfo geoIpInfo, @Nullable MRGSError error) {
if (geoIpInfo != null) {
Log.d("MRGSDevice", "MRGSGeoIpInfo success: " + geoIpInfo);
} else {
Log.d("MRGSDevice", "MRGSGeoIpInfo failed: " + error);
}
}
});
Замечание
Результат запроса кэшируется в RAM на всю сессию приложения, поэтому если вы используете VPN для тестирования, вам нужно перезапустить приложение, чтобы получить новый результат.
Время установки приложения🔗
MRGS хранит время установки приложения. Для того чтобы получить время, достаточно обратиться к следующим функциям:
Дата создания: 2020-09-23