Перейти к содержимому

Справочник конфигурации

Все параметры SDK задаются через TracehubConfig до вызова Tracehub.initSdk(config:). Здесь же — сетевые настройки: собственные домены, HMAC-подпись запросов и TLS-пиннинг.

Параметр Тип Описание
appToken String Токен приложения из кабинета Tracehub
environment TracehubEnvironment .production или .sandbox

Уровень задаётся полем config.logLevel:

Значение Описание
.verbose Максимальная детализация
.debug Отладочные сообщения
.info Информационные (по умолчанию)
.warning Только предупреждения
.error Только ошибки
.none Логирование отключено
Обратный вызов Свойство конфигурации
Изменение атрибуции attributionChangedCallback
Успех сессии sessionSuccessCallback
Ошибка сессии sessionFailureCallback
Успех события eventSuccessCallback
Ошибка события eventFailureCallback
Отложенный диплинк deferredDeeplinkCallback
Обновление SKAdNetwork skanUpdatedCallback
Параметр По умолчанию Описание
externalDeviceId nil Собственный идентификатор устройства
customerUserId nil Идентификатор пользователя в вашей системе (например, после входа в учётную запись)
defaultTracker nil Токен трекинг-ссылки по умолчанию для органических установок
isIdfaEnabled true Чтение IDFA (при наличии ATT-разрешения)
isIdfvEnabled true Чтение IDFV

Приложение обычно узнаёт идентификатор пользователя только после входа, то есть позже initSdk. Поэтому кроме конфигурации есть методы времени выполнения:

// после успешного входа
Tracehub.setCustomerUserId("user-uuid")
// при выходе из учётной записи
Tracehub.clearCustomerUserId()

Значение уходит со всеми последующими запросами SDK и не сохраняется между запусками приложения — задавайте его заново при каждом старте, как только идентификатор известен. clearCustomerUserId() снимает и значение, заданное в TracehubConfig: разлогиненное устройство не должно сообщать прежнего пользователя.

Параметр / метод По умолчанию Описание
isCoppaEnabled false Режим COPPA — для приложений, ориентированных на детей до 13 лет
enableFirstSessionDelay() Не отправлять первую сессию до вызова Tracehub.endFirstSessionDelay()

Подробнее — см. страницу iOS SDK: приватность и идентификаторы.

Параметр / метод По умолчанию Описание
enableDeviceIdsReadingOnce() Читать IDFA только один раз за жизненный цикл SDK
enableLinkMe() Включить поддержку LinkMe (извлечение _dlt из входящих URL)
attConsentWaitingInterval 0 Пауза перед отправкой очереди (в секундах) для ожидания ATT-решения
disableSkanAttribution() Отключить автоматическое обновление значений SKAdNetwork
urlStrategyConfig nil Переопределить домены эндпоинтов
hmacSigningConfig nil HMAC-подпись всех запросов SDK
tlsConfig nil TLS-пиннинг и дополнительные доверенные сертификаты
disableTlsPinning false Отключить SPKI-проверку, сохранив доверенные сертификаты из tlsConfig

SDK автоматически управляет регистрацией конверсий SKAdNetwork. При необходимости значение конверсии можно обновить вручную:

// Базовое обновление (iOS 14+)
await Tracehub.updateSkanConversionValue(fineValue: 7)
// Расширенное обновление (iOS 16.1+)
await Tracehub.updateSkanConversionValue(
fineValue: 7,
coarseValue: "medium", // "low", "medium", "high"
lockWindow: false
)

Обратный вызов после обновления:

config.skanUpdatedCallback = { info in
print("SKAN конверсия: \(info["conversion_value"] ?? "-")")
if let error = info["error"] {
print("Ошибка SKAN: \(error)")
}
}

Отключить автоматическое управление: config.disableSkanAttribution().

Значением конверсии SKAdNetwork управляет SDK на устройстве. Итоговые постбэки SKAdNetwork Apple отправляет напрямую в рекламные сети — отдельного отчёта по SKAdNetwork-конверсиям в кабинете Tracehub нет; результаты кампаний смотрите в отчётах по установкам и событиям.

func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
let token = deviceToken.map { String(format: "%02x", $0) }.joined()
Tracehub.setPushToken(token)
}

Если используете Firebase, передавайте FCM-токен тем же вызовом Tracehub.setPushToken(_:) из MessagingDelegate.

Весь трафик SDK можно направить через свой домен:

config.urlStrategyConfig = URLStrategyConfig(
domains: ["analytics.mycompany.com"],
useSubdomains: false,
isDataResidency: true
)

При включённой подписи каждый исходящий запрос SDK содержит заголовок X-Tracehub-Signature с HMAC-SHA256-сигнатурой, привязанной к временному окну. Секретный ключ никогда не покидает устройство — передаётся только производная сигнатура. Сервер проверяет сигнатуру и отклоняет запросы с недействительной сигнатурой.

Формат заголовка:

X-Tracehub-Signature: v1:{app_token}:{unix_timestamp}:{hex_signature}

Включение:

let config = TracehubConfig(appToken: "{ВашТокен}", environment: .production)
config.hmacSigningConfig = HMACSigningConfig(secretKey: "{ВашСекретныйКлюч}")
Tracehub.initSdk(config: config)

Секретный ключ — в кабинете Tracehub: Трекинг → Приложения → выберите приложение → вкладка SDK, карточка «HMAC-секрет» (кнопки «Показать» и «Копировать»; у приложений, созданных до появления HMAC-подписи, ключ сначала создаётся кнопкой «Сгенерировать»). Ключ один на приложение — общий для iOS и Android.

Параметр bucketSizeSeconds задаёт ширину временного окна; по умолчанию — 300 с (5 мин). Сервер принимает текущее окно ± 1, что даёт допуск 3 × bucketSizeSeconds.

Перевыпуск ключа запускается там же, на карточке «HMAC-секрет»: новый ключ вступает в силу сразу, старый остаётся действительным ещё 48 часов, и в этот период сервер принимает оба ключа. Обновите ключ в приложении в течение этого окна. Обращаться в поддержку не нужно.

Пиннинг привязывает HTTPS-соединения SDK к конкретному набору SHA-256-отпечатков публичных ключей (SPKI). Даже скомпрометированный корневой сертификат в хранилище устройства не позволит перехватить трафик SDK без контроля над одним из запиненных ключей.

Пиннинг выключен по умолчанию и остаётся необязательным: без config.tlsConfig SDK проверяет соединения обычными системными правилами iOS.

Слой Метод Роль
Доверенные сертификаты addTrustAnchorFromPem(_:) / addTrustAnchorFromDer(_:) Расширяет системное хранилище доверия дополнительными CA-сертификатами — нужен, когда сервер использует CA, которого нет в системе (чаще всего корень Минцифры)
Пины публичных ключей addHostPin(_:primarySpki:backupSpki:) Требует, чтобы в цепочке сервера присутствовал один из двух указанных SPKI-отпечатков

Соединение проходит только при успехе обоих слоёв. Все методы настройки помечены throws: невалидный PEM, отсутствующий префикс sha256/, совпадающие primary- и backup-пины и пустой шаблон хоста вернут ошибку — конфигурируйте tlsConfig один раз при инициализации, чтобы ошибки всплыли на этапе тестирования.

Все эндпоинты *.tracehub.ru используют сертификаты публичного CA — достаточно пина на хост-маску:

let tls = TracehubTlsConfig()
try tls.addHostPin(
"*.tracehub.ru",
primarySpki: "sha256/ОТПЕЧАТОК_ТЕКУЩЕГО_INTERMEDIATE=",
backupSpki: "sha256/ОТПЕЧАТОК_СЛЕДУЮЩЕГО_INTERMEDIATE="
)
let config = TracehubConfig(appToken: "{ВашТокен}", environment: .production)
config.tlsConfig = tls
Tracehub.initSdk(config: config)

Маска *.tracehub.ru покрывает ровно одну метку: analytics.tracehub.ru, gdpr.tracehub.ru, subscription.tracehub.ru, ssrv.tracehub.ru и региональные поддомены. Вложенные поддомены (v2.api.tracehub.ru) маской не покрываются — при необходимости перечислите хосты явно.

Корень Минцифры (Russian Trusted Root CA) не входит в системное хранилище iOS — без дополнительного якоря соединение с хостом, использующим такой сертификат, упадёт ещё до проверки пинов. Положите PEM-файл в bundle приложения и подключите его:

guard let url = Bundle.main.url(forResource: "russian_trusted_root_ca",
withExtension: "pem") else {
fatalError("PEM Минцифры не найден в bundle")
}
let pem = try String(contentsOf: url, encoding: .ascii)
let tls = TracehubTlsConfig()
try tls.addTrustAnchorFromPem(pem)
try tls.addHostPin(
"ru.tracehub.ru",
primarySpki: "sha256/ОТПЕЧАТОК_SUB_CA_МИНЦИФРЫ=",
backupSpki: "sha256/РЕЗЕРВНЫЙ_ОТПЕЧАТОК="
)

Добавленные сертификаты дополняют системное хранилище, а не заменяют его: цепочка, подписанная либо системным CA, либо Минцифры, пройдёт проверку. PEM-файл с несколькими сертификатами (intermediate + root) поддерживается — каждый блок BEGIN CERTIFICATE разбирается отдельно.

Часть окружений несовместима с пиннингом: корпоративные прокси с инспекцией трафика (Zscaler, Cisco Umbrella, Netskope и т. п.), устройства под MDM-политикой с принудительной подменой сертификатов. Для таких случаев:

config.tlsConfig = tls // якоря доверия сохраняются
config.disableTlsPinning = true // SPKI-проверка выключается

disableTlsPinning отключает только проверку пинов, но сохраняет добавленные доверенные сертификаты — приложение за корпоративным прокси продолжит работать с хостами на сертификатах Минцифры. Если пины настроены, но пиннинг отключён, SDK при инициализации пишет предупреждение в лог.

Окно терминала
openssl s_client -servername analytics.tracehub.ru -connect analytics.tracehub.ru:443 \
< /dev/null 2>/dev/null \
| openssl x509 -pubkey -noout \
| openssl pkey -pubin -outform der \
| openssl dgst -sha256 -binary \
| base64

Запустите команду для каждого сертификата цепочки и пинуйте отпечаток intermediate. Поддерживаемые ключи: RSA 2048/3072/4096 и EC P-256/P-384; сертификат вне этого набора пин не даст.

Пин, потерявший актуальность, нельзя заменить без обновления приложения — поэтому у каждого хоста заранее есть backup-пин. Ротация в четыре шага между двумя релизами приложения:

  1. Выберите следующий intermediate CA и вычислите его SPKI-отпечаток.
  2. Выпустите версию приложения, где новый отпечаток прописан как backup рядом с текущим primary. Подождите раскатки по пользователям (~30 дней).
  3. Серверная цепочка ротируется на новый intermediate — устройства продолжают работать, backup-пин им уже известен. Регулярно перепроверяйте отпечатки командой из раздела «Вычисление SPKI-отпечатка».
  4. В следующем релизе прошлый backup становится primary, выбирается новый backup.

Для отладки с Charles, Proxyman или mitmproxy не выкатывайте отключение пиннинга в App Store-сборку. Варианты:

  • dev-сборка без tlsConfig — SDK работает без пиннинга, прокси перехватывает трафик после установки его системного сертификата;
  • disableTlsPinning = true во внутренней debug-сборке — если tlsConfig должен присутствовать (например, для проверки цепочки Минцифры);
  • urlStrategyConfig на свой dev-сервер — в паре с любым из вариантов выше.