SDK для iOS

Swift, можно вызывать из Objective-C. Без зависимостей. Включает манифест конфиденциальности. Тариф Pro и выше.

Требования

  • iOS 13+.
  • Swift или Objective-C.
  • Ключ SDK: в панели откройте приложение → Настройки → Ключи SDK → Новый ключ. Он показывается один раз, поэтому скопируйте его сразу.

Установка

В Xcode выберите File → Add Package Dependencies…, вставьте адрес репозитория, выберите Up to Next Major Version начиная с 0.3.3 и добавьте библиотеку Unolink в таргет приложения.

https://github.com/unolink-dev/unolink-sdk

Unolink устанавливается через Swift Package Manager, а не через CocoaPods. Если ваш проект использует CocoaPods для других библиотек и pod install падает с ошибкой кодировки (Ruby 4 или локаль не в UTF-8), запустите его в UTF-8:

LANG=en_US.UTF-8 pod install

Настройка

Вызовите configure один раз, как можно раньше: в init() вашего @main App или в application(_:didFinishLaunchingWithOptions:).

import Unolink

@main
struct MyApp: App {
    init() {
        #if DEBUG
        Unolink.configure(apiKey: "ulk_…", options: UnolinkOptions(debug: true))
        #else
        Unolink.configure(apiKey: "ulk_…")
        #endif
    }
    var body: some Scene { WindowGroup { ContentView() } }
}

Скомпилированная библиотека не видит ваших настроек сборки, поэтому передавайте debug: true из debug-сборок сами, как показано выше. Это помечает установку как тестовое устройство.

Objective-C:

@import Unolink;

[Unolink configureWithApiKey:@"ulk_…" options:[UNLOptions new]];

Параметры

ПараметрПо умолчаниюЧто делает
debugfalseПомечает эту установку как тестовое устройство. Панели скрывают тестовые устройства, если не включено Учитывать тестовые устройства.
logLevel.warnСколько выводится в консоль Xcode, с префиксом [Unolink]: .none, .error, .warn, .info, .debug.
baseURLhttps://api.unolink.devSDK API. Оставьте как есть.
Unolink.configure(apiKey: "ulk_…", options: UnolinkOptions(logLevel: .debug, debug: true))

Ключ публичный: он поставляется внутри вашего приложения и может отправлять данные только для этого одного приложения. См. Ключи SDK.

События воронки

Добавьте по одной строке в каждый важный момент. Они станут шагами в Воронке и «Путях».

Unolink.onboardingCompleted()                       // the last onboarding screen is done
Unolink.paywallViewed(placement: "onboarding")      // a paywall appeared; placement says which one
Unolink.paywallSkipped(placement: "onboarding")     // closed without buying
Unolink.signUp(method: "apple")                     // an account was created
Unolink.signUpSkipped()                             // went on as a guest (0.3.2+)

Без RevenueCat сообщайте о пробных периодах и покупках сами. Сумма имеет тип Decimal, поэтому цены никогда не округляются:

Unolink.trialStarted(productId: "pro_yearly")
Unolink.purchase(amount: product.price, currency: "USD", productId: product.id)
Unolink.purchaseCancelled(productId: product.id)    // closed the purchase sheet
Unolink.purchaseFailed(productId: product.id, reason: "payment_failed")

Ваши собственные события принимают имя и до 20 свойств:

Unolink.track("level_up", properties: ["level": 3])

Objective-C:

[Unolink paywallViewedWithPlacement:@"onboarding" properties:nil];
[Unolink purchaseWithAmount:[NSDecimalNumber decimalNumberWithString:@"49.99"] currency:@"USD" productId:nil properties:nil];

Полный список с названиями, которые попадают в панель, — в разделе События.

ID пользователя и RevenueCat

Если вы используете RevenueCat, подключите его в приложении → Настройки → RevenueCat. Тогда не вызывайте purchase и trialStarted: RevenueCat сам отправляет пробные периоды, покупки, продления, отмены и возвраты, а Unolink игнорирует вызовы покупок из приложения, чтобы ничего не учитывалось дважды.

Чтобы привязать эти покупки к установке, сообщайте собственный app user ID RevenueCat. В SDK 0.3.2 и новее одна строка поддерживает его в актуальном состоянии. Вызовите её один раз при запуске, до или после configure:

Unolink.connectRevenueCat { Purchases.isConfigured ? Purchases.shared.appUserID : nil }

Unolink считывает ID при запуске, каждый раз, когда приложение становится активным, и перед каждым событием, и отправляет его, только если он изменился. После Purchases.logIn и Purchases.logOut вызывайте Unolink.revenueCatUserChanged(), чтобы сразу отправить новый ID. Возвращайте nil, пока RevenueCat не настроен: обращение к Purchases.shared до этого останавливает приложение.

Без этого (или до версии 0.3.2) вызывайте setUserId с ID из RevenueCat после Purchases.configure, после каждого Purchases.logIn и Purchases.logOut и при каждом запуске. Используйте что-то одно, а не оба способа сразу:

// after Purchases.configure, logIn and logOut, and on every launch
Unolink.setUserId(Purchases.shared.appUserID)

Для гостя это анонимный ID RevenueCat, поэтому покупка, сделанная до регистрации, сразу привязывается к установке. После logIn это ID аккаунта. Учитываются все ID, которые сообщала установка, поэтому покупка гостя остаётся привязанной. См. Гости и аккаунты.

Unolink никогда не хранит сам ID, только односторонний хеш, который у каждого вашего приложения свой.

Отложенные диплинки есть только на Android. Apple не даёт приложениям реферер установки, поэтому приложению нельзя сообщить, по какой ссылке нажали, а Unolink никогда не использует фингерпринтинг устройств, чтобы это угадать. Unolink.onDeferredDeepLink(_:) существует, чтобы код можно было использовать на разных платформах, но на iPhone сейчас он не вызывается.

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

Ваши ссылки по-прежнему отправляют посетителей с iPhone прямо в App Store и считают их клики, а SDK по-прежнему считает каждую установку и каждое событие.

Другие вызовы

ВызовЧто делает
Unolink.installIdСлучайный ID этой установки или nil до configure. Он не идентифицирует ни человека, ни устройство.
Unolink.flush()Отправляет события из очереди прямо сейчас. Обычно не нужен.
Unolink.setEnabled(false)Отключает отслеживание и удаляет события из очереди, для вашей настройки отказа. true включает его снова.

Как он работает

  • Первый запуск: создаёт случайный ID установки в Application Support (исключён из резервной копии iCloud, никогда не в Keychain), поэтому переустановка или новый телефон — это новая установка.
  • Автоматические события: first_open, session_start (при запуске или после 30 минут в фоне) и app_background. Они бесплатны.
  • События хранятся на устройстве (до 1000) и отправляются пакетами каждые 15 секунд, пока приложение активно, а также когда оно уходит в фон. Без сети они ждут и отправляются повторно.
  • Он никогда не блокирует главный поток и никогда не выбрасывает исключений.

Тестовые устройства

Настраивайте с debug: true в debug-сборках, как показано выше. Их данные настоящие, но скрыты, пока вы не включите Включать тестовые устройства в Воронке и «Путях». Подробнее в разделе Тестирование.

Конфиденциальность

  • Без IDFA, без запроса App Tracking Transparency, без фингерпринтинга.
  • Встроенный манифест конфиденциальности объявляет взаимодействие с продуктом (ваши события) и историю покупок (покупки, о которых вы сообщаете), используемые для аналитики, не связанной с личностью, и отсутствие отслеживания. Используйте те же ответы в ярлыке конфиденциальности App Store.
  • Случайный ID установки, версия приложения, версия ОС, версия SDK, телефон или планшет, язык. Страна определяется на границе сети. IP-адреса никогда не хранятся.
  • Никогда не передавайте имена, email или другие персональные данные в свойствах событий.

Решение проблем

  • В панели ничего нет? Включите Учитывать тестовые устройства: debug-сборки с debug: true по умолчанию скрыты.
  • Всё равно ничего? Настройте с UnolinkOptions(logLevel: .debug, debug: true) и ищите в консоли Xcode [Unolink]. Неверный или отозванный ключ записывается в лог как ошибка.
  • У некоторых установок на iPhone нет ссылки? Так и должно быть: не каждую установку на iPhone можно сопоставить с кликом, и такие установки показываются отдельной строкой. См. Диплинки на iPhone.

Подробнее в разделе Решение проблем.