Skip to main content
DATALYR provides native SDKs for iOS (Swift) and React Native, enabling mobile app tracking with attribution, SKAdNetwork support, and offline queuing.

What It Does

Mobile App Tracking:
  • iOS SDK (Swift) for native Apple apps
  • React Native SDK for cross-platform apps
  • Automatic session tracking
  • Attribution tracking (App Store, organic)
  • SKAdNetwork conversion value encoding
  • Offline event queue
  • App lifecycle tracking

iOS SDK (Swift)

Installation

Swift Package Manager: Xcode:
  1. File → Add Packages
  2. Enter: https://github.com/datalyr/datalyr-ios-sdk
  3. Select version: 1.0.0+
Package.swift:
dependencies: [
  .package(url: "https://github.com/datalyr/datalyr-ios-sdk", from: "1.0.0")
]

Basic Usage

Initialize SDK:
import DatalyrSDK

// In AppDelegate or App struct
try await DatalyrSDK.shared.initialize(config: DatalyrConfig(
  workspaceId: "your_workspace_id",
  apiKey: "dk_your_api_key",
  debug: true
))
Track Events:
// Track custom event
await DatalyrSDK.shared.track("button_tap", eventData: [
  "button_name": "signup",
  "screen": "onboarding"
])

// Track with revenue
await DatalyrSDK.shared.track("purchase", eventData: [
  "revenue": 99.99,
  "currency": "USD",
  "product_id": "prod_123"
])
Identify Users:
// After login
await DatalyrSDK.shared.identify("user_123", properties: [
  "email": "[email protected]",
  "name": "John Doe",
  "plan": "pro"
])
Track Screens:
// Track screen view
await DatalyrSDK.shared.screen("Home Screen", properties: [
  "tab": "feed"
])
Reset on Logout:
// Clear user identity
await DatalyrSDK.shared.reset()

Configuration Options

let config = DatalyrConfig(
  workspaceId: "your_workspace_id",
  apiKey: "dk_your_api_key",
  debug: false,
  endpoint: "https://api.datalyr.com",

  // Queue settings
  maxRetries: 3,
  retryDelay: 1000,
  timeout: 15000,
  batchSize: 10,
  flushInterval: 30000,
  maxQueueSize: 100,

  // Privacy
  respectDoNotTrack: true,

  // Auto-events
  enableAutoEvents: true,
  enableAttribution: true,

  // SKAdNetwork
  skadTemplate: "ecommerce"  // or "gaming", "subscription"
)

SKAdNetwork Support

Initialize with SKAdNetwork:
// Use template for automatic conversion value encoding
try await DatalyrSDK.initializeWithSKAdNetwork(
  config: config,
  template: "ecommerce"
)
Track with Automatic Encoding:
// Automatically updates SKAdNetwork conversion value
await DatalyrSDK.trackWithSKAdNetwork("purchase", eventData: [
  "revenue": 99.99,
  "currency": "USD"
])

// Convenience method for purchases
await DatalyrSDK.trackPurchase(
  value: 99.99,
  currency: "USD",
  productId: "prod_123"
)

// Convenience method for subscriptions
await DatalyrSDK.trackSubscription(
  value: 9.99,
  currency: "USD",
  plan: "monthly"
)
Test Conversion Values:
// Get conversion value without sending to Apple
let value = DatalyrSDK.getConversionValue(
  for: "purchase",
  properties: ["revenue": 99.99]
)
print("Conversion value: \(value ?? 0)")
Available Templates:
  • "ecommerce": Revenue-based encoding (0-6 brackets)
  • "gaming": Level progression and IAP
  • "subscription": Trial, active, churned states

Auto-Events

Automatically Tracked:
  • app_install: First launch
  • app_open: App foreground
  • app_close: App background
  • session_start: New session
  • session_end: Session timeout
Enable/Disable:
let config = DatalyrConfig(
  workspaceId: "your_workspace_id",
  apiKey: "dk_your_api_key",
  enableAutoEvents: false  // Disable auto-events
)

Attribution

Automatic Attribution: SDK captures attribution data on install:
  • App Store referrer
  • Campaign parameters
  • Install timestamp
Get Attribution Data:
let attribution = DatalyrSDK.shared.getAttributionData()
print("Attribution source: \(attribution.source ?? "unknown")")
Set Attribution Manually:
await DatalyrSDK.shared.setAttributionData(AttributionData(
  source: "facebook",
  medium: "cpc",
  campaign: "summer_sale"
))

Session Management

Get Session Info:
// Current session ID
let sessionId = DatalyrSDK.shared.getStatus().sessionId

// Current session data
let session = DatalyrSDK.shared.getCurrentSession()
Manual Session Control:
// End session manually
await DatalyrSDK.shared.endSession()

Advanced Features

Flush Manually:
// Flush queued events immediately
await DatalyrSDK.shared.flush()
Get SDK Status:
let status = DatalyrSDK.shared.getStatus()
print("Initialized: \(status.initialized)")
print("Visitor ID: \(status.visitorId)")
print("Queue size: \(status.queueStats.queueSize)")
Get Anonymous ID:
let anonId = DatalyrSDK.shared.getAnonymousId()
Track Revenue Events:
await DatalyrSDK.shared.trackRevenue("subscription_renewal", properties: [
  "value": 9.99,
  "currency": "USD",
  "plan": "monthly"
])

SwiftUI Integration

import SwiftUI
import DatalyrSDK

@main
struct MyApp: App {
  init() {
    Task {
      try await DatalyrSDK.shared.initialize(config: DatalyrConfig(
        workspaceId: "your_workspace_id",
        apiKey: "dk_your_api_key"
      ))
    }
  }

  var body: some Scene {
    WindowGroup {
      ContentView()
    }
  }
}

struct ContentView: View {
  var body: some View {
    Button("Track Event") {
      Task {
        await DatalyrSDK.shared.track("button_tap")
      }
    }
  }
}

React Native SDK

Installation

npm install @datalyr/react-native-sdk
Requirements:
  • React Native 0.60+
  • iOS 13+ / Android 5.0+

Basic Usage

Initialize SDK:
import { Datalyr } from '@datalyr/react-native-sdk';

// In App.tsx or index.js
await Datalyr.initialize({
  workspaceId: 'your_workspace_id',
  apiKey: 'dk_your_api_key',
  debug: true
});
Track Events:
// Track custom event
await Datalyr.track('button_tap', {
  button_name: 'signup',
  screen: 'onboarding'
});

// Track with revenue
await Datalyr.track('purchase', {
  revenue: 99.99,
  currency: 'USD',
  product_id: 'prod_123'
});
Identify Users:
// After login
await Datalyr.identify('user_123', {
  email: '[email protected]',
  name: 'John Doe',
  plan: 'pro'
});
Track Screens:
// Track screen view
await Datalyr.screen('HomeScreen', {
  tab: 'feed'
});
Reset on Logout:
// Clear user identity
await Datalyr.reset();

Configuration Options

await Datalyr.initialize({
  workspaceId: 'your_workspace_id',
  apiKey: 'dk_your_api_key',
  debug: false,
  endpoint: 'https://api.datalyr.com',

  // Queue settings
  maxRetries: 3,
  retryDelay: 1000,
  timeout: 15000,
  batchSize: 10,
  flushInterval: 30000,
  maxQueueSize: 100,

  // Privacy
  respectDoNotTrack: true,

  // Auto-events
  enableAutoEvents: true,
  enableAttribution: true,

  // SKAdNetwork (iOS only)
  skadTemplate: 'ecommerce'
});

SKAdNetwork Support (iOS)

Track with Automatic Encoding:
// Automatically updates SKAdNetwork conversion value (iOS only)
await Datalyr.trackWithSKAdNetwork('purchase', {
  revenue: 99.99,
  currency: 'USD'
});

// Convenience method for purchases
await Datalyr.trackPurchase(99.99, 'USD', 'prod_123');

// Convenience method for subscriptions
await Datalyr.trackSubscription(9.99, 'USD', 'monthly');
Test Conversion Values:
// Get conversion value without sending to Apple
const value = Datalyr.getConversionValue('purchase', { revenue: 99.99 });
console.log('Conversion value:', value);

Auto-Events

Automatically Tracked:
  • app_install: First launch
  • app_open: App foreground
  • app_close: App background
  • session_start: New session
  • session_end: Session timeout
Configuration:
await Datalyr.initialize({
  workspaceId: 'your_workspace_id',
  apiKey: 'dk_your_api_key',
  enableAutoEvents: true,
  autoEventConfig: {
    trackAppLifecycle: true,
    trackScreenViews: true,
    trackDeepLinks: true,
    sessionTimeout: 1800000  // 30 minutes
  }
});

Attribution

Get Attribution Data:
const attribution = Datalyr.getAttributionData();
console.log('Attribution source:', attribution.source);
Set Attribution Manually:
await Datalyr.setAttributionData({
  source: 'facebook',
  medium: 'cpc',
  campaign: 'summer_sale'
});

Session Management

Get Session Info:
const status = Datalyr.getStatus();
console.log('Session ID:', status.sessionId);

const session = Datalyr.getCurrentSession();
console.log('Session started:', session.startTime);
Manual Session Control:
// End session manually
await Datalyr.endSession();

Advanced Features

Flush Manually:
// Flush queued events immediately
await Datalyr.flush();
Get SDK Status:
const status = Datalyr.getStatus();
console.log('Initialized:', status.initialized);
console.log('Visitor ID:', status.visitorId);
console.log('Queue size:', status.queueStats.queueSize);
Get Anonymous ID:
const anonId = Datalyr.getAnonymousId();
Alias User:
// Connect anonymous user to known user
await Datalyr.alias('user_123', 'previous_id');

React Navigation Integration

import { NavigationContainer } from '@react-navigation/native';
import { Datalyr } from '@datalyr/react-native-sdk';

function App() {
  const navigationRef = useRef();
  const routeNameRef = useRef();

  return (
    <NavigationContainer
      ref={navigationRef}
      onReady={() => {
        routeNameRef.current = navigationRef.current.getCurrentRoute().name;
      }}
      onStateChange={async () => {
        const previousRouteName = routeNameRef.current;
        const currentRouteName = navigationRef.current.getCurrentRoute().name;

        if (previousRouteName !== currentRouteName) {
          // Track screen view
          await Datalyr.screen(currentRouteName);
        }

        routeNameRef.current = currentRouteName;
      }}
    >
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Profile" component={ProfileScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

TypeScript Support

Full TypeScript definitions included:
import { Datalyr, DatalyrConfig, EventData } from '@datalyr/react-native-sdk';

const config: DatalyrConfig = {
  workspaceId: 'your_workspace_id',
  apiKey: 'dk_your_api_key',
  debug: true
};

await Datalyr.initialize(config);

const eventData: EventData = {
  revenue: 99.99,
  currency: 'USD'
};

await Datalyr.track('purchase', eventData);

Common Use Cases

E-commerce App

// Product view
await Datalyr.track('product_view', {
  product_id: 'prod_123',
  name: 'Premium Widget',
  price: 99.99
});

// Add to cart
await Datalyr.track('add_to_cart', {
  product_id: 'prod_123',
  quantity: 2
});

// Purchase (with SKAdNetwork on iOS)
await Datalyr.trackPurchase(199.98, 'USD', 'prod_123');

Subscription App

// Trial start
await Datalyr.track('trial_start', {
  plan: 'pro',
  duration: 14
});

// Subscription (with SKAdNetwork on iOS)
await Datalyr.trackSubscription(9.99, 'USD', 'monthly');

// Subscription cancel
await Datalyr.track('subscription_cancel', {
  plan: 'monthly',
  reason: 'too_expensive'
});

Gaming App

// Level complete
await Datalyr.trackWithSKAdNetwork('level_complete', {
  level: 5,
  score: 1250,
  time: 180
});

// In-app purchase
await Datalyr.trackPurchase(4.99, 'USD', 'coins_1000');

// Achievement unlocked
await Datalyr.track('achievement', {
  achievement_id: 'first_win',
  points: 100
});

Best Practices

Initialize Early: Initialize SDK in AppDelegate (iOS) or index.js (React Native) before any events. Flush Before Exit: SDK automatically flushes on app background, but manually call flush() for critical events. Handle Offline: SDK queues events offline and sends when connection restored. Test Conversion Values: Use getConversionValue() to test SKAdNetwork encoding before production. Privacy: Enable respectDoNotTrack and collect user consent before tracking.

Migrating from AppsFlyer / Adjust

DATALYR provides similar functionality to AppsFlyer and Adjust with a simpler integration and bundled platform SDKs.

From AppsFlyer

// BEFORE: AppsFlyer
import appsFlyer from 'react-native-appsflyer';
appsFlyer.initSdk({ devKey: 'YOUR_DEV_KEY', appId: 'YOUR_APP_ID' });
appsFlyer.logEvent('af_purchase', { af_revenue: 99.99, af_currency: 'USD' });

// AFTER: DATALYR
import { Datalyr } from '@datalyr/react-native-sdk';
await Datalyr.initialize({ apiKey: 'dk_your_api_key' });
await Datalyr.trackPurchase(99.99, 'USD', 'product_id');

From Adjust

// BEFORE: Adjust
import { Adjust, AdjustConfig, AdjustEvent } from 'react-native-adjust';
const config = new AdjustConfig('YOUR_TOKEN', AdjustConfig.EnvironmentProduction);
Adjust.create(config);
const event = new AdjustEvent('abc123');
event.setRevenue(99.99, 'USD');
Adjust.trackEvent(event);

// AFTER: DATALYR
import { Datalyr } from '@datalyr/react-native-sdk';
await Datalyr.initialize({ apiKey: 'dk_your_api_key' });
await Datalyr.trackPurchase(99.99, 'USD');

Event Name Mapping

AppsFlyer EventAdjust EventDATALYR Method
af_purchasePURCHASEtrackPurchase()
af_add_to_cartADD_TO_CARTtrackAddToCart()
af_initiated_checkoutINITIATE_CHECKOUTtrackInitiateCheckout()
af_complete_registrationCOMPLETE_REGISTRATIONtrackCompleteRegistration()
af_content_viewVIEW_CONTENTtrackViewContent()
af_searchSEARCHtrackSearch()
af_subscribeSUBSCRIBEtrackSubscription()

Migration Benefits

  • Bundled SDKs: Meta and TikTok SDKs included, no extra packages
  • Unified API: Single SDK for all platforms and ad networks
  • Web-to-App: Automatic attribution matching via email
  • Flat Pricing: No per-MAU charges

Troubleshooting

Events Not Appearing

Check SDK Status:
const status = Datalyr.getStatus();
console.log('Initialized:', status.initialized);
console.log('Queue size:', status.queueStats.queueSize);
Enable Debug Mode:
await Datalyr.initialize({
  apiKey: 'dk_your_api_key',
  debug: true,
});
Force Flush Events:
await Datalyr.flush();
Verify API Key:
  • Should start with dk_
  • Check Settings → API Keys in dashboard

iOS Build Errors

cd ios
pod deintegrate
pod cache clean --all
pod install

Android Build Errors

cd android && ./gradlew clean
npx react-native run-android

Meta SDK Not Working

Verify Info.plist contains:
<key>FacebookAppID</key>
<string>YOUR_APP_ID</string>
<key>FacebookClientToken</key>
<string>YOUR_CLIENT_TOKEN</string>
Check status: Datalyr.getPlatformIntegrationStatus()

TikTok SDK Not Working

Ensure both app IDs are provided:
await Datalyr.initialize({
  apiKey: 'dk_your_api_key',
  tiktok: {
    appId: 'your_tiktok_app_id',
    tiktokAppId: '7123456789012345',
  },
});

Attribution Not Captured

Enable attribution in config:
await Datalyr.initialize({
  apiKey: 'dk_your_api_key',
  enableAttribution: true,
});
Check data:
const attribution = Datalyr.getAttributionData();
console.log(attribution);

SKAdNetwork Not Working

  • iOS 14.0+ required (iOS 16.1+ for SKAN 4.0)
  • Set skadTemplate in config
  • Use trackWithSKAdNetwork() for automatic encoding
  • Test with getConversionValue() first

App Tracking Transparency (iOS 14.5+)

import { requestTrackingPermissionsAsync } from 'expo-tracking-transparency';

const { status } = await requestTrackingPermissionsAsync();
await Datalyr.updateTrackingAuthorization(status === 'granted');

Platform Requirements

iOS SDK:
  • iOS 13.0+
  • Xcode 14+
  • Swift 5.5+
React Native SDK:
  • React Native 0.60+
  • iOS 13+ / Android 5.0+
  • Node.js 14+

Next Steps