<!--
AppSprint docs markdown
Canonical HTML: https://appsprint.app/docs/react-native
Markdown URL: https://appsprint.app/docs/react-native.md
Docs index: https://appsprint.app/docs.md
Sitemap: https://appsprint.app/sitemap.xml
LLM guide: https://appsprint.app/llms.txt
-->

# React Native / Expo

Installation, configuration, event tracking, and full API reference for the React Native / Expo SDK.

## Requirements

- React Native 0.71+
- React 18+
- iOS 14.0+ and Android API 21+

## 1. Install

npm

```bash
npm install appsprint-react-native

# iOS only
cd ios && pod install
```

> For Expo prebuild, add the config plugin to app.json and run npx expo prebuild. The plugin injects NSUserTrackingUsageDescription on iOS and INTERNET / AD_ID on Android.

[View on npm](https://www.npmjs.com/package/appsprint-react-native)

## 2. Configure

```tsx
import { AppSprint } from 'appsprint-react-native';

// Call as early as possible. App.tsx, root layout, or _layout.tsx.
await AppSprint.configure({
  apiKey: 'as_live_xxxxx',
});
```

Non-blocking. configure() resolves after local state is restored; install registration runs in the background on the native side. Lifecycle observers register automatically.

### Configuration options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `apiKey` | `string` | — | Your live API key (starts with as_live_). |
| `apiUrl` | `string` | https://api.appsprint.app | Override for staging or self-hosted environments. |
| `enableAppleAdsAttribution` | `boolean` | true | iOS only. Fetches Apple AdServices at install time. |
| `customerUserId` | `string | null` | null | Your internal user ID. Persists across launches and replays automatically if the first send fails. |
| `autoTrackSessions` | `boolean` | true | Fires session_start on configure() and on foreground, debounced to one event per 30 minutes. |
| `autoRefreshAttribution` | `boolean` | true | Refetches /v1/sdk/attribution on configure() and foreground transitions. |
| `googleAdsConsent` | `GoogleAdsConsent | null` | null | Optional Google Ads ad user data consent forwarded as consent.adUserData on Google Ads uploads. |
| `isDebug` | `boolean` | false | Forces debug-level logging on the native side. |
| `logLevel` | `0 | 1 | 2 | 3` | 2 (WARN) | 0 = DEBUG, 1 = INFO, 2 = WARN, 3 = ERROR. |

## 3. Track events

```tsx
// Standard event
await AppSprint.sendEvent('login');
```

```tsx
// Revenue event. Currency must be a 3-letter ISO code.
await AppSprint.sendEvent('purchase', null, {
  revenue: 9.99,
  currency: 'USD',
});
```

```tsx
// Custom event with parameters
await AppSprint.sendEvent('custom', 'level_complete', {
  level: 5,
  score: 1200,
});
```

### Supported event types

`session_start`, `login`, `sign_up`, `register`, `purchase`, `subscribe`, `start_trial`, `add_payment_info`, `add_to_cart`, `add_to_wishlist`, `initiate_checkout`, `view_content`, `view_item`, `search`, `share`, `tutorial_complete`, `achieve_level`, `level_start`, `level_complete`, `custom`

## 4. Read attribution

```tsx
const attr = await AppSprint.getAttribution();
console.log(attr?.source);         // "apple_ads", "tracking_link", or "organic"
console.log(attr?.isAttributed);   // boolean
console.log(attr?.campaignName);   // Campaign name when available
console.log(attr?.appleAds?.campaignId);
console.log(attr?.link?.name);
```

## API reference

### `configure(config)` → Promise<void>

Initializes the SDK. Resolves after local state is restored; install registration runs in the background.

```tsx
await AppSprint.configure({ apiKey: '…' })
```

### `sendEvent(type, name?, params?)` → Promise<void>

Enqueues an event locally and schedules a flush.

```tsx
await AppSprint.sendEvent('purchase', null, { revenue: 9.99, currency: 'USD' })
```

type is a string literal — see event types below.

### `flush()` → Promise<void>

Drains the queue immediately. Safe to call repeatedly.

```tsx
await AppSprint.flush()
```

### `refreshAttribution()` → Promise<AttributionResult | null>

Fetches the latest attribution from the backend. Self-heals a 404 install_not_found by re-running install.

```tsx
const attr = await AppSprint.refreshAttribution()
```

### `setCustomerUserId(id)` → Promise<void>

Updates the customer user ID. Sent immediately if install is registered; otherwise queued and retried automatically.

```tsx
await AppSprint.setCustomerUserId('user-123')
```

### `getAppSprintId()` → Promise<string | null>

Returns the install ID, or null before install registration completes.

```tsx
const id = await AppSprint.getAppSprintId()
```

### `getAttribution()` → Promise<AttributionResult | null>

Returns the cached AttributionResult.

```tsx
const attr = await AppSprint.getAttribution()
```

### `getAttributionParams()` → Promise<Record<string, string>>

Partner-ready flat payload for forwarding to RevenueCat, Superwall, etc.

```tsx
const params = await AppSprint.getAttributionParams()
```

### `enableAppleAdsAttribution()` → Promise<boolean>

Re-enables Apple Ads at runtime on iOS. Returns false on Android.

```tsx
await AppSprint.enableAppleAdsAttribution()
```

### `isInitialized()` → Promise<boolean>

True once configure() resolved.

```tsx
await AppSprint.isInitialized()
```

### `isSdkDisabled()` → Promise<boolean>

True if a 401 or 403 permanently disabled the SDK.

```tsx
await AppSprint.isSdkDisabled()
```

### `sendTestEvent()` → Promise<{ success, message }>

Posts a diagnostic event and resolves to (success, message).

```tsx
const result = await AppSprint.sendTestEvent()
```

### `clearData()` → Promise<void>

Wipes local state and the event queue. Removes lifecycle observers.

```tsx
await AppSprint.clearData()
```

### `destroy()`

Removes native lifecycle observers without wiping data.

```tsx
AppSprint.destroy()
```


## Offline behavior

- Events that fail to send are automatically queued in native storage (up to 100 events).
- The queue persists across app restarts.
- Queued events are retried automatically when configure() completes, when the app moves to the background, or when you call flush().
- If a queued event receives a 401/403, the SDK disables itself and clears the queue.

## Platform notes

- The JS layer is a thin bridge. Behavior matches the standalone native iOS and Android SDKs.
- On iOS, ATT must be requested while the app is foreground-active. NativeAppSprint.requestTrackingAuthorization() waits for that state internally.
- On iOS, AdServices runs on iOS 14.3+. Older OS versions skip Apple Ads attribution silently.
- On Android, GAID is read off the main thread, honoring Limit Ad Tracking and dropping the all-zero advertising ID.
- Events persist to native storage (UserDefaults on iOS, SharedPreferences on Android) and survive app restarts. Maximum queue size is 100 events.
- iOS uses URLSession with waitsForConnectivity = true. Transient offline windows queue inside the OS.
- On Expo, the bundled config plugin injects NSUserTrackingUsageDescription, INTERNET, and AD_ID during prebuild.

## Troubleshooting

**getAppSprintId() returns null**
configure() resolves before install registration finishes on the native side. Retry briefly, or read the value after the first event has been sent.

**Events do not appear in dashboard**
Confirm the API key starts with as_live_. Call sendTestEvent() and inspect the returned message.

**SDK disabled (isSdkDisabled returns true)**
The API returned 401 or 403. Call clearData(), then configure() with a valid key.

**Apple Ads attribution not detected**
AdServices requires a real device (not the simulator). Confirm enableAppleAdsAttribution is true and that the test build is signed with a real provisioning profile.

**pod install fails after adding the package**
Delete ios/Podfile.lock and ios/Pods, then run pod install --repo-update.

**Android build cannot find AD_ID**
The package's manifest declares com.google.android.gms.permission.AD_ID and is merged at build time. If you target an app that cannot use it, remove with tools:node="remove".

## Connectivity test

```tsx
const result = await AppSprint.sendTestEvent();
console.log(result.success, result.message);
```

## Verification checklist

1. Create a blank Expo or bare React Native app and install the package.
2. Call configure() in App.tsx or your root layout.
3. Verify getAppSprintId() returns a value after first launch.
4. Send login, purchase, and custom events. Confirm they appear in the dashboard.
5. Send an event offline, background the app, restore connectivity, relaunch. Verify the event lands.
6. Call sendTestEvent() and confirm success is true.

---

## Docs navigation

Use the Markdown URLs when reading the docs programmatically. Use the HTML URLs when you need the interactive docs UI.

- [Overview](https://appsprint.app/docs) ([Markdown](https://appsprint.app/docs.md)) — Introduction to AppSprint
- [Quickstart](https://appsprint.app/docs/quickstart) ([Markdown](https://appsprint.app/docs/quickstart.md)) — Get up and running in 5 minutes
- [React Native](https://appsprint.app/docs/react-native) ([Markdown](https://appsprint.app/docs/react-native.md)) — React Native / Expo SDK reference
- [iOS (Swift)](https://appsprint.app/docs/ios-swift) ([Markdown](https://appsprint.app/docs/ios-swift.md)) — Native Swift SDK reference
- [Android (Kotlin)](https://appsprint.app/docs/android) ([Markdown](https://appsprint.app/docs/android.md)) — Native Android SDK reference
- [Flutter](https://appsprint.app/docs/flutter) ([Markdown](https://appsprint.app/docs/flutter.md)) — Flutter plugin reference
- [RevenueCat](https://appsprint.app/docs/revenuecat) ([Markdown](https://appsprint.app/docs/revenuecat.md)) — Webhook integration for subscription attribution
- [Superwall](https://appsprint.app/docs/superwall) ([Markdown](https://appsprint.app/docs/superwall.md)) — Webhook integration for paywall attribution
- [Apple Search Ads](https://appsprint.app/docs/apple-search-ads) ([Markdown](https://appsprint.app/docs/apple-search-ads.md)) — Campaign and keyword attribution
- [Google Ads](https://appsprint.app/docs/google-ads) ([Markdown](https://appsprint.app/docs/google-ads.md)) — Offline click conversion upload
- [TikTok Ads](https://appsprint.app/docs/tiktok-ads) ([Markdown](https://appsprint.app/docs/tiktok-ads.md)) — Events API server-side event forwarding
