iOS SDK
Kixo iOS SDK поддерживает Swift 5.9+ и iOS 16+: аналитику, атрибуцию, push-уведомления, отслеживание жизненного цикла и повторы сессий. Для повтора сессий используются проектные переключатели записи и осторожные настройки по умолчанию для более тяжёлых этапов обработки; отдельных минимальных требований к версии OS или модели устройства сверх deployment target iOS 16 у пакета нет. SDK распространяется через Swift Package Manager и после одного вызова Kixo.configure автоматически отслеживает экраны, нажатия, сессии, сбои, push-уведомления и события жизненного цикла. Отслеживание сетевых запросов включается отдельно.
Установка
Swift Package Manager
В Xcode откройте File → Add Package Dependencies и введите:
https://github.com/kixoio/kixo-ios-sdkЕсли вы управляете зависимостями через Package.swift, используйте бинарный релизный пакет и продукт:
dependencies: [
.package(
url: "https://github.com/kixoio/kixo-ios-sdk",
from: "1.0.21"
),
],
targets: [
.target(
name: "YourApp",
dependencies: [
.product(name: "Kixo", package: "kixo-ios-sdk"),
]
)
]Настройка
Инициализируйте Kixo в структуре App для SwiftUI или в AppDelegate:
import Kixo
@main
struct MyApp: App {
init() {
Kixo.configure(
projectId: "YOUR_PROJECT_ID",
apiKey: "YOUR_API_KEY"
)
}
var body: some Scene {
WindowGroup { ContentView() }
}
}Примечание
Достаточно одной строки. SDK по умолчанию использует production-окружение, управляемый ingest-хост и включает стандартные автотрекеры. Переопределяйте отдельные флаги через ConfigurationOptions(...) только при необходимости.
Параметры конфигурации
Kixo.configure(
projectId: "YOUR_PROJECT_ID",
apiKey: "YOUR_API_KEY",
options: ConfigurationOptions(
autoTrackScreens: true,
autoTrackTaps: true,
autoTrackNetwork: false,
autoTrackCrashes: true,
autoTrackSessions: true,
autoTrackPush: true,
sessionTimeout: 30,
flushInterval: 30,
flushAt: 20,
maxBufferSize: 200,
// apiHost: nil → managed Kixo ingest host
// debug: nil → true in DEBUG, false otherwise
// environment: nil → production
)
)Примечание
Конфигурация с сервера. Любой флаг отдельного трекера можно переключить и на странице Settings → Data Collection в дашборде. Настройки проекта могут переопределять локальные значения по умолчанию.
Автоматически отслеживаемые события
screen_view— мгновенные появления контроллеров UIKit и навигация SwiftUIscreen_visit— структурированный визит, который завершается при навигации или переходе приложения в фон; включает время пребывания, счётчики вовлечённости, идентификатор экрана и метаданные потокаsession_start/session_endtap— нажатия на кнопки и распознаватели жестовcrash— диагностические данные о сбоях и исключенияхnetwork— необязательные обезличенные агрегаты запросов и диагностика маршрутовpush_received/push_open/push_dismissed/push_silent/push_action— полный жизненный цикл push-уведомленийpush_permission/push_token_invalidatedlifecycle— переходы между foreground, background и запуском приложения
Пользовательские события
Kixo.track("purchase_completed", properties: [
"product_id": "SKU-123",
"amount": 49.99,
"currency": "USD",
])Типизированные хелперы событий
Удобная обёртка над Kixo.track для событий, которые Kixo распознаёт по имени (purchase, signup, subscribe_start, trial_start, cancel, upgrade, activation, share, invite). Даёт проверку структуры свойств на этапе компиляции и единый источник истины для имён ключей — детектор стандартных событий на бэкенде сопоставляет их дословно.
Kixo.trackPurchase(
amount: 49.99,
currency: "USD",
productId: "pro_yearly"
)
Kixo.trackSubscriptionStart(
plan: "pro",
amount: 9.99,
currency: "USD",
interval: .month
)
Kixo.trackSignup(method: "google")
Kixo.trackTrialStart(plan: "pro", days: 14)
Kixo.trackCancel(plan: "pro", reason: "too_expensive")
Kixo.trackUpgrade(fromPlan: "free", toPlan: "pro")
Kixo.trackActivation(event: "first_post_published")
Kixo.trackShare(channel: "twitter", contentId: "post_123")
Kixo.trackInvite(channel: "email", recipientCount: 5)Идентификация пользователей
У зарезервированных ключей стандартных свойств есть префикс $ (соглашение Mixpanel), поэтому они не пересекаются с вашими пользовательскими traits и выводятся в колонках профиля в дашборде. Используйте типизированный enum StandardProperty или обычную строку с префиксом $; полный список из 37 ключей приведён ниже в Каталог стандартных свойств.
Kixo.identify("user_123", traits: [
"$email": "jane@example.com", // identity
"$name": "Jane Doe", // identity
"$plan": "pro", // subscription pack
"$lifetime_orders": 12, // e-commerce pack
"signup_source": "twitter_ad" // custom trait
])Пометить пользователя для сегментации
Используйте setUserProperty со значением булево значение, чтобы добавить пользователю простой тег «да/нет». Тег сохраняется между сессиями и используется в сегментах, email-кампаниях и запросах в чате — кроме вызова SDK ничего настраивать не нужно.
// Tag a user as subscribed — segments + campaigns can target this
Kixo.setUserProperty("subscribe", value: true)
// VIP membership
Kixo.setUserProperty("vip", value: true)
// String + numeric values work too
Kixo.setUserProperty("plan_tier", value: "enterprise")
Kixo.setUserProperty("lifetime_orders", value: 42)
// Bulk-set
Kixo.setUserProperties([
"subscribe": true,
"plan_tier": "enterprise",
])Свойства сохраняются в UserDefaults между запусками и автоматически добавляются ко всем исходящим событиям. В чате можно писать, например, "отправить приветственное письмо пользователям, у которых subscribe = true", — Kixo сам соберёт сегмент и подготовит черновик шаблона. Очищаются при Kixo.reset().
Каталог стандартных свойств
Зарезервированные ключи свойств используют префикс $, чтобы не пересекаться с вашими пользовательскими traits. В каталоге Kixo — 37 ключей: 3 универсальных набора (identity, geo, lifecycle) и 5 отраслевых наборов для B2B (subscription, e-commerce, media, marketplace, loyalty). Задавайте только те, что подходят вашему продукту, — в дашборде будут показаны только заполненные наборы.
Идентификация
Используется всегда. Задаёт колонки в заголовке профиля.
| Ключ | Тип | Описание |
|---|---|---|
$email | строка | Основной email; часто используется как ключ для объединения профилей. |
$phone | строка | Номер телефона в формате E.164. |
$name | строка | Полное отображаемое имя. |
$first_name | строка | Имя. |
$last_name | строка | Фамилия. |
$avatar_url | строка | Полный URL аватара пользователя. |
Геоданные
Географический контекст.
| Ключ | Тип | Описание |
|---|---|---|
$country | строка | Код страны по ISO 3166. |
$city | строка | Название города. |
$region | строка | Штат или провинция. |
$timezone | строка | Часовой пояс IANA, например America/Los_Angeles. |
$language | строка | Тег IETF, например en или ru-RU. |
$locale | строка | Полный идентификатор локали. |
Жизненный цикл
Когда мы видели этого пользователя.
| Ключ | Тип | Описание |
|---|---|---|
$created | ISO8601 | Время регистрации или создания аккаунта. |
$last_seen | ISO8601 | Время последнего взаимодействия. |
Подписка
Используйте, если в вашем продукте есть тарифы.
| Ключ | Тип | Описание |
|---|---|---|
$plan | строка | Slug тарифа — free, pro, enterprise. |
$subscription_status | строка | active / trial / cancelled / past_due. |
$trial_ends | ISO8601 | Когда заканчивается текущий пробный период. |
$mrr | число | Ежемесячная регулярная выручка в валюте аккаунта. |
$subscription_started | ISO8601 | Когда началась текущая подписка. |
Электронная коммерция
Используйте, если продаёте товары.
| Ключ | Тип | Описание |
|---|---|---|
$lifetime_orders | число | Количество завершённых заказов. |
$lifetime_revenue | число | Общие расходы. |
$aov | число | Средний чек. |
$last_purchase | ISO8601 | Последняя успешная покупка. |
$first_purchase | ISO8601 | Первая успешная покупка. |
$cart_abandoned_count | число | Общее число брошенных корзин. |
Медиа
Используйте, если публикуете контент.
| Ключ | Тип | Описание |
|---|---|---|
$content_tier | строка | free / premium / paid. |
$subscribed_categories | CSV-строка или массив | Категории, на которые подписан пользователь. |
$watch_time_total | число | Общее время просмотра в секундах. |
$last_played | ISO8601 | Время последнего начала воспроизведения. |
Маркетплейс
Используйте, если ваш продукт — двусторонняя платформа.
| Ключ | Тип | Описание |
|---|---|---|
$seller_tier | строка | Slug уровня на стороне продавца. |
$buyer_tier | строка | Slug уровня на стороне покупателя. |
$listings_count | число | Активные объявления пользователя. |
$reviews_count | число | Отзывы, полученные пользователем. |
$verified | булево значение | Статус KYC. |
Лояльность
Используйте для программ вовлечения и вознаграждений.
| Ключ | Тип | Описание |
|---|---|---|
$loyalty_points | число | Текущий доступный баланс баллов. |
$vip_level | строка | Slug уровня VIP. |
$referral_count | число | Успешные рефералы, засчитанные этому пользователю. |
Совет
Не нашли подходящий вариант? Используйте обычные ключи для пользовательских traits. Они появятся в панели Custom Traits в дашборде и не будут засорять колонки профиля. Пять отраслевых наборов выше — это практичные заготовки для самых распространённых моделей B2B; терминология конкретного продукта, например shipping_plan, остаётся без префикса.
Super-properties
Пары ключ/значение на уровне сессии, которые автоматически добавляются к каждому исходящему событию. В отличие от traits в identify, описывающих личность пользователя, super-properties описывают контекст сессии: активный вариант A/B-теста, тип сборки, включённые feature flags. Сохраняются в UserDefaults между запусками и очищаются при reset(). Если ключи совпадают, приоритет всегда у properties в track.
Kixo.setSuperProperty("build_flavor", value: "beta")
Kixo.setSuperProperties([
"ab_variant": "B",
"referrer_campaign": "autumn-launch",
])
// Sugar for A/B tracking — keys as 'experiment_<id>'.
Kixo.setExperimentVariant("checkout_v2", variant: "variant_a")
Kixo.unsetSuperProperty("build_flavor")
Kixo.clearSuperProperties()Отслеживание экранов в SwiftUI
В SwiftUI просмотры экранов отслеживаются автоматически, если SDK может определить имя представления. Если нужен более точный контроль или собственные имена, используйте модификатор представления .kixoScreen():
struct HomeView: View {
var body: some View {
VStack { Text("Welcome") }
.kixoScreen("HomeView")
}
}Запись сессий
Replay воссоздаёт то, что пользователь действительно видел: SDK захватывает кадры экрана в формате HEIC вместе со структурным снимком иерархии представлений, а проигрыватель в дашборде собирает из этого воспроизведение с перемоткой рядом с временной шкалой событий. Настройте replay для проекта в Панель управления → Настройки → Повтор сеанса; SDK сам загрузит эту политику и будет обновлять её во время работы приложения.
Kixo.configure(
projectId: "YOUR_PROJECT_ID",
apiKey: "YOUR_API_KEY"
)В дашборде задаётся, включён ли replay, маскирование, режимы захвата и можно ли загружать нативный replay по сотовой сети. Если загрузка по сотовой сети отключена, кадры всё равно могут сохраняться в ограниченный локальный буфер на устройстве; отправка начнётся, когда появится разрешённая сеть.
SDK собирает данные, включённые в проекте, а также события и свойства, которые отправляет ваше приложение.
Маскирование и приватность
Поскольку replay захватывает пиксели, скрытие происходит на устройстве до кодирования любого кадра. Пароли и другие чувствительные поля определяются и скрываются автоматически, а текст из структурного снимка проходит через фильтр PII. Чтобы скрыть свои данные — личную переписку, баланс счёта или экран черновика, — задайте kxRedact для нужного представления. Kixo накладывает сплошной прямоугольник по границам этого представления ещё до кодирования в HEIC, поэтому его пиксели не покидают устройство.
balanceLabel.kxRedact = true
cardNumberField.kxRedact = trueСовет
Нажатия, зафиксированные при записи экранов, также попадают в мобильную тепловую карту в дашборде, поэтому вы видите, куда пользователи нажимают на каждом экране без дополнительной настройки SDK. Replay зависит от тарифа проекта; если захват кадров недоступен, SDK всё равно записывает метаданные сессии, но не загружает поток кадров.
Push-уведомления
SDK устанавливает runtime-прокси AppDelegate на Kixo.configure: silent push-уведомления (content-available: 1) и видимые push-уведомления, доставленные в фоне, фиксируются автоматически. Ничего добавлять в AppDelegate не нужно. Существующие реализации UNUserNotificationCenterDelegate продолжают вызываться как обычно: Kixo просто оборачивает их.
Зарегистрируйте токен устройства через стандартный didRegisterForRemoteNotificationsWithDeviceToken:
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
let token = deviceToken.map { String(format: "%02x", $0) }.joined()
Kixo.setPushToken(token)
}Если приложение использует Firebase Messaging, передайте его registration token через provider: .firebase. Kixo сохранит этого провайдера и будет доставлять сообщения через FCM HTTP v1; перед отправкой кампаний настройте в Kixo сервисный аккаунт Firebase для этого приложения.
func messaging(_ messaging: Messaging, didReceiveRegistrationToken token: String?) {
guard let token else { return }
Kixo.setPushToken(token, provider: .firebase)
}Отправка данных и работа офлайн
SDK ставит события в локальную очередь, отправляет их пакетами и повторяет попытки при временных сбоях с увеличивающейся задержкой. Если сбор данных приостановлен в настройках проекта, новые события не отправляются, пока вы не включите его снова.
Диагностика
Снимок состояния только для чтения. Удобен на экранах отладки и в smoke-тестах: помогает понять, почему события не отправляются, без отладчика.
let diag = Kixo.diagnostics()
print(diag.queue.bufferedEventCount) // events waiting to flush
print(diag.paused) // collection paused state
print(diag.environment) // configured environment
print(diag.apiHost) // configured ingest hostПринудительно отправить всё сейчас (для тестов)
Синхронная перегрузка, которая блокирует поток до timeout секунд, пока не завершится flush. Предназначена для фикстур XCTest — никогда не вызывайте её из главного потока.
func testEventLanded() {
Kixo.track("test_event")
let landed = Kixo.flush(timeout: 5.0)
XCTAssertTrue(landed)
}Сбросить
Очищает identity, super-properties и сохранённую очередь. Вызывайте при выходе из аккаунта, чтобы следующие события не привязывались к предыдущему пользователю.
Kixo.reset()