📱 Мобильные SDK
Официальные SDK для iOS (Swift) и Android (Kotlin/Java) с полной поддержкой всех возможностей InstantBase
🎯 Что вы получите
- Нативный SDK для каждой платформы с оптимальной производительностью
- Автоматическое управление сессиями и идентификаторами устройств
- Автосохранение событий при отсутствии сети
- Поддержка пуш-уведомлений и глубокой интеграции с устройством
- Готовые методы для отслеживания экранов, покупок, ошибок
📱 iOS SDK (Swift)
iOS 13.0+
Swift 5.5+
Установка
// В Xcode: File → Add Packages...
// Вставьте URL репозитория:
https://github.com/instantbase/ios-sdk.git
// Или добавьте в Package.swift
dependencies: [
.package(url: "https://github.com/instantbase/ios-sdk.git", from: "1.0.0")
]
# Podfile
platform :ios, '13.0'
use_frameworks!
target 'YourApp' do
pod 'InstantBaseSDK', '~> 1.0.0'
end
# Скачайте последнюю версию SDK с GitHub
# Добавьте InstantBaseSDK.xcframework в проект
# В Build Settings → Other Linker Flags добавьте -ObjC
Инициализация
import UIKit
import InstantBaseSDK
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Базовая инициализация
InstantBase.configure(
apiKey: "your_api_key",
options: Configuration(
environment: .production,
debug: true,
autoTrackScreen: true,
autoTrackAppLifecycle: true,
sessionTimeout: 30 // минут
)
)
// Установка идентификатора пользователя (если есть)
if let userId = getCurrentUserId() {
InstantBase.shared.identify(userId: userId)
}
return true
}
}
Конфигурация
Configuration
Параметры конфигурации
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
environment |
Environment | .production |
.production или .development |
debug |
Bool | false |
Логирование в консоль |
autoTrackScreen |
Bool | true |
Автоотслеживание экранов |
autoTrackAppLifecycle |
Bool | true |
Отслеживание app_open/app_close |
sessionTimeout |
Int | 30 |
Минут неактивности для новой сессии |
maxBatchSize |
Int | 20 |
Размер батча для отправки |
flushInterval |
Int | 10 |
Интервал отправки (секунды) |
let config = Configuration(
environment: .development,
debug: true,
autoTrackScreen: true,
autoTrackAppLifecycle: true,
sessionTimeout: 15,
maxBatchSize: 50,
flushInterval: 5
)
InstantBase.configure(apiKey: "test_key", options: config)
Основные методы
track()
Отправка события
import InstantBaseSDK
// Простое событие
InstantBase.shared.track(
event: "button_tap",
properties: [
"button_id": "signup",
"screen": "welcome"
]
)
// Событие с пользователем
InstantBase.shared.track(
event: "purchase",
properties: [
"user_id": "user_123",
"order_id": "ORD-001",
"amount": 1499.99
],
metadata: [
"is_order": true,
"funnel_sales_step": 4
]
)
// Анонимный пользователь (автоматически)
InstantBase.shared.track(
event: "page_view",
properties: [
"page": "products"
]
)
identify()
Идентификация пользователя
// При авторизации
InstantBase.shared.identify(
userId: "user_123",
traits: [
"email": "user@example.com",
"name": "Иван Петров",
"plan": "premium"
]
)
// С метаданными атрибутов
InstantBase.shared.identify(
userId: "user_123",
traits: [
"email": "user@example.com",
"plan": "premium"
],
metadata: [
"plan": [
"attribute_display_name": "Тариф",
"attribute_category": "Подписка"
]
]
)
trackScreen()
Отслеживание экрана
// Ручное отслеживание
InstantBase.shared.trackScreen(
screenName: "ProductDetailViewController",
screenTitle: "Товар",
properties: [
"product_id": "prod_123"
]
)
// Автоматически (если включено autoTrackScreen)
// SDK автоматически отслеживает появление ViewController'ов
alias()
Связывание идентификаторов
// При входе в аккаунт
let anonymousId = InstantBase.shared.getAnonymousId()
InstantBase.shared.alias(previousId: anonymousId, newId: "user_123")
reset()
Сброс пользователя
// При выходе из аккаунта
InstantBase.shared.reset()
// С новым anonymous_id
InstantBase.shared.reset(generateNewId: true)
Отслеживание покупок (StoreKit)
import StoreKit
import InstantBaseSDK
extension StoreKitManager {
func handlePurchase(transaction: SKPaymentTransaction) {
let product = transaction.payment.productIdentifier
// Отслеживаем покупку
InstantBase.shared.track(
event: "iap_purchase",
properties: [
"product_id": product,
"price": getPrice(for: product),
"currency": "RUB"
],
metadata: [
"is_order": true,
"event_display_name": "Покупка в приложении"
]
)
// Обновляем атрибуты пользователя
InstantBase.shared.identify(traits: [
"last_purchase": Date().ISO8601Format(),
"total_purchases": getUserPurchaseCount()
])
}
}
Отслеживание пуш-уведомлений
import UserNotifications
import InstantBaseSDK
class NotificationService: UNNotificationServiceExtension {
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
// Пуш получен
InstantBase.shared.track(
event: "push_received",
properties: [
"campaign": request.identifier,
"category": request.content.categoryIdentifier
]
)
// ... обработка пуша
}
}
// В AppDelegate
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
// Пуш открыт
InstantBase.shared.track(
event: "push_opened",
properties: [
"campaign": response.notification.request.identifier,
"action": response.actionIdentifier
]
)
completionHandler()
}
}
Отслеживание ошибок
import InstantBaseSDK
// Глобальный обработчик ошибок
NSSetUncaughtExceptionHandler { exception in
InstantBase.shared.track(
event: "crash",
properties: [
"reason": exception.reason ?? "unknown",
"name": exception.name.rawValue,
"stack": exception.callStackSymbols.joined(separator: "\n")
],
metadata: [
"event_display_name": "Краш",
"event_color": "#dc3545"
]
)
}
// Отслеживание ошибок API
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
InstantBase.shared.track(
event: "network_error",
properties: [
"error": error.localizedDescription,
"url": url.absoluteString
]
)
}
}.resume()
Интеграция с SwiftUI
import SwiftUI
import InstantBaseSDK
struct ProductView: View {
let productId: String
let productName: String
@State private var appeared = false
var body: some View {
VStack {
Text(productName)
Button("Купить") {
purchase()
}
}
.onAppear {
if !appeared {
// Отслеживаем просмотр
InstantBase.shared.trackScreen(
screenName: "ProductView",
screenTitle: productName,
properties: ["product_id": productId]
)
appeared = true
}
}
}
func purchase() {
InstantBase.shared.track(
event: "purchase",
properties: [
"product_id": productId,
"product_name": productName
],
metadata: ["is_order": true]
)
}
}
Оффлайн-режим
// SDK автоматически сохраняет события при отсутствии сети
// и отправляет их при восстановлении соединения
// Ручное управление
InstantBase.shared.setOffline(true) // принудительно в оффлайн
InstantBase.shared.setOffline(false) // выход из оффлайна
// Проверка статуса
let isOffline = InstantBase.shared.isOffline
let unsentCount = InstantBase.shared.unsentEventsCount
// Принудительная отправка
InstantBase.shared.flush()
🤖 Android SDK (Kotlin/Java)
Android 5.0+ (API 21+)
Kotlin 1.5+
Установка
// build.gradle (project)
allprojects {
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
// build.gradle (app)
dependencies {
implementation 'com.github.instantbase:android-sdk:1.0.0'
implementation 'com.google.code.gson:gson:2.9.0'
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
}
<dependency>
<groupId>com.github.instantbase</groupId>
<artifactId>android-sdk</artifactId>
<version>1.0.0</version>
</dependency>
# Скачайте AAR файл с GitHub
# Поместите в app/libs/
# Добавьте в build.gradle:
implementation files('libs/instantbase-sdk.aar')
Инициализация
import com.instantbase.InstantBase
import com.instantbase.Configuration
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
// Базовая инициализация
InstantBase.initialize(
context = this,
apiKey = "your_api_key",
configuration = Configuration(
environment = Environment.PRODUCTION,
debug = BuildConfig.DEBUG,
autoTrackScreen = true,
autoTrackAppLifecycle = true,
sessionTimeout = 30,
maxBatchSize = 20,
flushInterval = 10
)
)
// Установка идентификатора пользователя
val userId = getCurrentUserId()
if (userId != null) {
InstantBase.getInstance().identify(userId)
}
}
}
Конфигурация
Configuration
Параметры конфигурации
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
environment |
Environment | PRODUCTION |
PRODUCTION или DEVELOPMENT |
debug |
Boolean | false |
Логирование в Logcat |
autoTrackScreen |
Boolean | true |
Автоотслеживание экранов |
autoTrackAppLifecycle |
Boolean | true |
Отслеживание app_open/app_close |
sessionTimeout |
Int | 30 |
Минут неактивности для новой сессии |
maxBatchSize |
Int | 20 |
Размер батча для отправки |
flushInterval |
Int | 10 |
Интервал отправки (секунды) |
val config = Configuration(
environment = Environment.DEVELOPMENT,
debug = true,
autoTrackScreen = true,
autoTrackAppLifecycle = true,
sessionTimeout = 15,
maxBatchSize = 50,
flushInterval = 5
)
InstantBase.initialize(context = this, apiKey = "test_key", configuration = config)
Основные методы
track()
Отправка события
import com.instantbase.InstantBase
// Kotlin
val ib = InstantBase.getInstance()
// Простое событие
ib.track(
event = "button_tap",
properties = mapOf(
"button_id" to "signup",
"screen" to "welcome"
)
)
// Событие с метаданными
ib.track(
event = "purchase",
properties = mapOf(
"user_id" to "user_123",
"order_id" to "ORD-001",
"amount" to 1499.99
),
metadata = mapOf(
"is_order" to true,
"funnel_sales_step" to 4
)
)
// Java
InstantBase.getInstance().track(
"button_tap",
new HashMap() {{
put("button_id", "signup");
put("screen", "welcome");
}},
null
);
identify()
Идентификация пользователя
// Kotlin
ib.identify(
userId = "user_123",
traits = mapOf(
"email" to "user@example.com",
"name" to "Иван Петров",
"plan" to "premium"
)
)
// С метаданными
ib.identify(
userId = "user_123",
traits = mapOf(
"email" to "user@example.com",
"plan" to "premium"
),
metadata = mapOf(
"plan" to mapOf(
"attribute_display_name" to "Тариф",
"attribute_category" to "Подписка"
)
)
)
// Java
InstantBase.getInstance().identify(
"user_123",
new HashMap() {{
put("email", "user@example.com");
put("name", "Иван Петров");
}},
null
);
trackScreen()
Отслеживание экрана
// Ручное отслеживание
ib.trackScreen(
screenName = "ProductActivity",
screenTitle = "Товар",
properties = mapOf(
"product_id" to "prod_123"
)
)
// В Activity
override fun onResume() {
super.onResume()
InstantBase.getInstance().trackScreen(
screenName = this::class.simpleName ?: "Unknown",
screenTitle = title.toString()
)
}
alias()
Связывание идентификаторов
// При входе в аккаунт
val anonymousId = ib.getAnonymousId()
ib.alias(anonymousId, "user_123")
reset()
Сброс пользователя
// При выходе
ib.reset()
// С новым anonymous_id
ib.reset(generateNewId = true)
Отслеживание покупок (Google Play Billing)
import com.android.billingclient.api.*
import com.instantbase.InstantBase
class BillingManager(private val context: Context) : PurchasesUpdatedListener {
private val ib = InstantBase.getInstance()
override fun onPurchasesUpdated(
billingResult: BillingResult,
purchases: MutableList?
) {
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) {
for (purchase in purchases) {
handlePurchase(purchase)
}
}
}
private fun handlePurchase(purchase: Purchase) {
// Отслеживаем покупку
ib.track(
event = "iap_purchase",
properties = mapOf(
"product_id" to purchase.products.first(),
"purchase_token" to purchase.purchaseToken,
"order_id" to purchase.orderId
),
metadata = mapOf(
"is_order" to true,
"event_display_name" to "Покупка в приложении"
)
)
// Обновляем атрибуты
ib.identify(traits = mapOf(
"last_purchase" to System.currentTimeMillis(),
"total_purchases" to getPurchaseCount()
))
}
}
Отслеживание пуш-уведомлений (Firebase)
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import com.instantbase.InstantBase
class MyFirebaseMessagingService : FirebaseMessagingService() {
private val ib by lazy { InstantBase.getInstance() }
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
// Пуш получен
ib.track(
event = "push_received",
properties = mapOf(
"campaign" to remoteMessage.messageId,
"title" to (remoteMessage.notification?.title ?: ""),
"category" to (remoteMessage.notification?.channelId ?: "")
)
)
// Показать уведомление...
}
override fun onNewToken(token: String) {
super.onNewToken(token)
// Обновляем FCM токен в профиле
ib.identify(traits = mapOf(
"fcm_token" to token,
"push_enabled" to true
))
}
}
// В Activity при клике на уведомление
Intent intent = getIntent();
if (intent.getExtras() != null) {
InstantBase.getInstance().track(
"push_opened",
mapOf("campaign" to intent.getStringExtra("message_id")),
null
);
}
Отслеживание ошибок
import com.instantbase.InstantBase
import java.lang.Thread
class CustomExceptionHandler : Thread.UncaughtExceptionHandler {
private val defaultHandler = Thread.getDefaultUncaughtExceptionHandler()
private val ib = InstantBase.getInstance()
override fun uncaughtException(t: Thread, e: Throwable) {
// Отслеживаем краш
ib.track(
event = "crash",
properties = mapOf(
"exception" to e.javaClass.simpleName,
"message" to (e.message ?: ""),
"stacktrace" to e.stackTraceToString()
),
metadata = mapOf(
"event_display_name" to "Краш",
"event_color" to "#dc3545"
)
)
// Принудительная отправка
ib.flush()
// Вызываем стандартный обработчик
defaultHandler?.uncaughtException(t, e)
}
}
// В Application.onCreate()
Thread.setDefaultUncaughtExceptionHandler(CustomExceptionHandler())
Интеграция с Jetpack Compose
import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import com.instantbase.InstantBase
@Composable
fun TrackScreen(
screenName: String,
screenTitle: String,
properties: Map? = null
) {
val lifecycleOwner = LocalLifecycleOwner.current
val ib = InstantBase.getInstance()
DisposableEffect(lifecycleOwner) {
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_RESUME) {
ib.trackScreen(screenName, screenTitle, properties)
}
}
lifecycleOwner.lifecycle.addObserver(observer)
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
}
}
@Composable
fun ProductScreen(productId: String, productName: String) {
TrackScreen(
screenName = "ProductScreen",
screenTitle = productName,
properties = mapOf("product_id" to productId)
)
Column {
Text(productName)
Button(onClick = {
InstantBase.getInstance().track(
event = "purchase",
properties = mapOf(
"product_id" to productId,
"product_name" to productName
),
metadata = mapOf("is_order" to true)
)
}) {
Text("Купить")
}
}
}
Оффлайн-режим
// SDK использует Room для локального хранения
// События автоматически сохраняются при отсутствии сети
// Проверка статуса
val isOffline = ib.isOffline
val unsentCount = ib.getUnsentEventsCount()
// Принудительная отправка
ib.flush()
// Ручное управление
ib.setOffline(true) // перейти в оффлайн
ib.setOffline(false) // выйти из оффлайна
// Слушатель сети
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
connectivityManager.registerNetworkCallback(
NetworkRequest.Builder().build(),
object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
ib.setOffline(false)
ib.flush()
}
override fun onLost(network: Network) {
ib.setOffline(true)
}
}
)
Общие возможности
📱 iOS
- ✅ Swift Package Manager
- ✅ CocoaPods
- ✅ SwiftUI интеграция
- ✅ StoreKit поддержка
- ✅ UserNotifications
- ✅ Background fetch
- ✅ iCloud sync
🤖 Android
- ✅ Gradle / Maven
- ✅ Kotlin coroutines
- ✅ Jetpack Compose
- ✅ Google Play Billing
- ✅ Firebase Cloud Messaging
- ✅ WorkManager
- ✅ Room persistence
Рекомендации для мобильных приложений
- Включайте autoTrackScreen — это даст понимание популярности экранов
- Отслеживайте версии приложения — чтобы видеть влияние обновлений
- Используйте оффлайн-режим — события не потеряются при отсутствии сети
- Настраивайте батчинг — для экономии трафика и батареи
- Отслеживайте краши — критически важно для качества
- Используйте пуш-трекинг — чтобы оценивать эффективность кампаний
⚠️ ВАЖНО: Для работы в продакшене обязательно используйте правильные API-ключи. В development используйте тестовые ключи. Никогда не храните ключи в коде — используйте secure storage или remote config.
Тестирование
// iOS - XCTest
func testTracking() {
let expectation = expectation(description: "Event tracked")
InstantBase.shared.track(event: "test_event") { result in
switch result {
case .success:
expectation.fulfill()
case .failure(let error):
XCTFail("Failed: \(error)")
}
}
wait(for: [expectation], timeout: 5.0)
}
// Android - JUnit
@Test
fun testTracking() = runBlockingTest {
val job = launch {
InstantBase.getInstance().track(
event = "test_event",
properties = mapOf("test" to true)
)
}
job.join()
// Проверяем, что событие сохранилось в БД
assertTrue(InstantBase.getInstance().getUnsentEventsCount() > 0)
}
Что дальше?
Нужна помощь с мобильной интеграцией?
Напишите нам, и мы поможем настроить SDK под ваше приложение