@datalyr/react-native 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -141
- package/LICENSE +21 -0
- package/README.md +405 -217
- package/datalyr-react-native.podspec +31 -0
- package/ios/DatalyrNative.m +70 -0
- package/ios/DatalyrNative.swift +275 -0
- package/ios/DatalyrSKAdNetwork.m +26 -0
- package/lib/datalyr-sdk.d.ts +64 -3
- package/lib/datalyr-sdk.js +322 -3
- package/lib/index.d.ts +1 -0
- package/lib/index.js +4 -2
- package/lib/integrations/index.d.ts +6 -0
- package/lib/integrations/index.js +6 -0
- package/lib/integrations/meta-integration.d.ts +76 -0
- package/lib/integrations/meta-integration.js +218 -0
- package/lib/integrations/tiktok-integration.d.ts +82 -0
- package/lib/integrations/tiktok-integration.js +356 -0
- package/lib/native/DatalyrNativeBridge.d.ts +31 -0
- package/lib/native/DatalyrNativeBridge.js +168 -0
- package/lib/native/index.d.ts +5 -0
- package/lib/native/index.js +5 -0
- package/lib/types.d.ts +29 -0
- package/package.json +10 -5
- package/src/datalyr-sdk-expo.ts +957 -0
- package/src/datalyr-sdk.ts +419 -19
- package/src/expo.ts +38 -18
- package/src/index.ts +5 -2
- package/src/integrations/index.ts +7 -0
- package/src/integrations/meta-integration.ts +238 -0
- package/src/integrations/tiktok-integration.ts +360 -0
- package/src/native/DatalyrNativeBridge.ts +271 -0
- package/src/native/index.ts +11 -0
- package/src/types.ts +39 -0
- package/src/utils-expo.ts +25 -3
- package/src/utils-interface.ts +38 -0
- package/EXPO_INSTALL.md +0 -297
- package/INSTALL.md +0 -402
- package/examples/attribution-example.tsx +0 -377
- package/examples/auto-events-example.tsx +0 -403
- package/examples/example.tsx +0 -250
- package/examples/skadnetwork-example.tsx +0 -380
- package/examples/test-implementation.tsx +0 -163
package/EXPO_INSTALL.md
DELETED
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
# Datalyr Expo SDK - Installation Guide
|
|
2
|
-
|
|
3
|
-
## Expo Compatibility
|
|
4
|
-
|
|
5
|
-
The Datalyr SDK works with all Expo workflows:
|
|
6
|
-
|
|
7
|
-
- **Expo Bare Workflow** - Full compatibility (use regular React Native SDK)
|
|
8
|
-
- **Expo Managed Workflow** - Requires Expo-specific setup (this guide)
|
|
9
|
-
- **Expo Go** - Limited compatibility due to native dependencies
|
|
10
|
-
|
|
11
|
-
## Quick Setup for Expo Managed Workflow
|
|
12
|
-
|
|
13
|
-
### 1. Install Expo Dependencies
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
# Navigate to your Expo project
|
|
17
|
-
cd your-expo-app
|
|
18
|
-
|
|
19
|
-
# Install Expo-compatible dependencies
|
|
20
|
-
npx expo install @react-native-async-storage/async-storage
|
|
21
|
-
npx expo install expo-application
|
|
22
|
-
npx expo install expo-constants
|
|
23
|
-
npx expo install expo-device
|
|
24
|
-
npx expo install expo-network
|
|
25
|
-
npx expo install expo-tracking-transparency
|
|
26
|
-
npx expo install react-native-get-random-values
|
|
27
|
-
|
|
28
|
-
# Install additional dependencies
|
|
29
|
-
npm install uuid
|
|
30
|
-
npm install --save-dev @types/uuid
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### 2. Update app.json/app.config.js
|
|
34
|
-
|
|
35
|
-
Add required permissions and configuration:
|
|
36
|
-
|
|
37
|
-
```json
|
|
38
|
-
{
|
|
39
|
-
"expo": {
|
|
40
|
-
"name": "Your App",
|
|
41
|
-
"version": "1.0.0",
|
|
42
|
-
"permissions": [
|
|
43
|
-
"INTERNET",
|
|
44
|
-
"ACCESS_NETWORK_STATE"
|
|
45
|
-
],
|
|
46
|
-
"ios": {
|
|
47
|
-
"infoPlist": {
|
|
48
|
-
"NSUserTrackingUsageDescription": "This app uses tracking to provide personalized ads and analytics.",
|
|
49
|
-
"CFBundleURLTypes": [
|
|
50
|
-
{
|
|
51
|
-
"CFBundleURLName": "your.app.identifier",
|
|
52
|
-
"CFBundleURLSchemes": ["yourappscheme"]
|
|
53
|
-
}
|
|
54
|
-
]
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
"android": {
|
|
58
|
-
"permissions": [
|
|
59
|
-
"INTERNET",
|
|
60
|
-
"ACCESS_NETWORK_STATE"
|
|
61
|
-
],
|
|
62
|
-
"intentFilters": [
|
|
63
|
-
{
|
|
64
|
-
"action": "VIEW",
|
|
65
|
-
"autoVerify": true,
|
|
66
|
-
"data": [
|
|
67
|
-
{
|
|
68
|
-
"scheme": "yourappscheme"
|
|
69
|
-
}
|
|
70
|
-
],
|
|
71
|
-
"category": [
|
|
72
|
-
"BROWSABLE",
|
|
73
|
-
"DEFAULT"
|
|
74
|
-
]
|
|
75
|
-
}
|
|
76
|
-
]
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### 3. Copy Expo-Compatible SDK Files
|
|
83
|
-
|
|
84
|
-
```bash
|
|
85
|
-
# Create SDK directory
|
|
86
|
-
mkdir -p src/datalyr-sdk
|
|
87
|
-
|
|
88
|
-
# Copy the Expo-compatible files
|
|
89
|
-
# You'll need to create these based on the original SDK but using Expo APIs
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### 4. Initialize in Your Expo App
|
|
93
|
-
|
|
94
|
-
```typescript
|
|
95
|
-
// App.tsx
|
|
96
|
-
import React, { useEffect } from 'react';
|
|
97
|
-
import 'react-native-get-random-values'; // Important: Must be imported first
|
|
98
|
-
import { datalyr } from '@datalyr/react-native-sdk';
|
|
99
|
-
|
|
100
|
-
const App: React.FC = () => {
|
|
101
|
-
useEffect(() => {
|
|
102
|
-
initializeDatalyr();
|
|
103
|
-
}, []);
|
|
104
|
-
|
|
105
|
-
const initializeDatalyr = async () => {
|
|
106
|
-
try {
|
|
107
|
-
await datalyr.initialize({
|
|
108
|
-
workspaceId: 'ozLZblQ8hN', // Your workspace ID
|
|
109
|
-
apiKey: 'dk_your_api_key', // Required for authentication
|
|
110
|
-
debug: true,
|
|
111
|
-
enableAttribution: true, // ✅ Deep link attribution tracking
|
|
112
|
-
autoEvents: {
|
|
113
|
-
trackSessions: true, // ✅ Automatic session tracking
|
|
114
|
-
trackScreenViews: true, // ✅ Automatic screen tracking
|
|
115
|
-
trackAppUpdates: true, // ✅ App version changes
|
|
116
|
-
trackPerformance: true, // ✅ App launch time, performance
|
|
117
|
-
sessionTimeoutMs: 30 * 60 * 1000, // 30 minutes
|
|
118
|
-
},
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
console.log('Datalyr Expo SDK initialized with auto-events!');
|
|
122
|
-
} catch (error) {
|
|
123
|
-
console.error('SDK init failed:', error);
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
// ... rest of your app
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
export default App;
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
## Expo vs React Native CLI Differences
|
|
134
|
-
|
|
135
|
-
| Feature | React Native CLI | Expo Managed | Expo Bare |
|
|
136
|
-
|---------|------------------|--------------|-----------|
|
|
137
|
-
| Device Info | `react-native-device-info` | `expo-device` + `expo-application` | `react-native-device-info` |
|
|
138
|
-
| IDFA/GAID | `react-native-idfa` | `expo-tracking-transparency` + setup | `react-native-idfa` |
|
|
139
|
-
| Network Detection | `@react-native-community/netinfo` | `expo-network` | `@react-native-community/netinfo` |
|
|
140
|
-
| Storage | `@react-native-async-storage/async-storage` | Same ✅ | Same ✅ |
|
|
141
|
-
| Attribution | Full support ✅ | Full support ✅ | Full support ✅ |
|
|
142
|
-
| Auto Events | Full support ✅ | Full support ✅ | Full support ✅ |
|
|
143
|
-
|
|
144
|
-
## Expo-Specific Features
|
|
145
|
-
|
|
146
|
-
### 1. Device Information
|
|
147
|
-
```typescript
|
|
148
|
-
// Uses expo-device and expo-application instead of react-native-device-info
|
|
149
|
-
import * as Device from 'expo-device';
|
|
150
|
-
import * as Application from 'expo-application';
|
|
151
|
-
|
|
152
|
-
const deviceInfo = {
|
|
153
|
-
model: Device.modelName,
|
|
154
|
-
manufacturer: Device.manufacturer,
|
|
155
|
-
osVersion: Device.osVersion,
|
|
156
|
-
appVersion: Application.nativeApplicationVersion,
|
|
157
|
-
buildNumber: Application.nativeBuildVersion,
|
|
158
|
-
bundleId: Application.applicationId,
|
|
159
|
-
isEmulator: !Device.isDevice,
|
|
160
|
-
};
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### 2. IDFA Permission (iOS)
|
|
164
|
-
```typescript
|
|
165
|
-
// Uses expo-tracking-transparency for iOS IDFA permission
|
|
166
|
-
import * as TrackingTransparency from 'expo-tracking-transparency';
|
|
167
|
-
|
|
168
|
-
const requestIDFAPermission = async () => {
|
|
169
|
-
if (Platform.OS === 'ios') {
|
|
170
|
-
const { status } = await TrackingTransparency.requestTrackingPermissionsAsync();
|
|
171
|
-
return status === TrackingTransparency.PermissionStatus.GRANTED;
|
|
172
|
-
}
|
|
173
|
-
return false;
|
|
174
|
-
};
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### 3. Network Detection
|
|
178
|
-
```typescript
|
|
179
|
-
// Uses expo-network instead of @react-native-community/netinfo
|
|
180
|
-
import * as Network from 'expo-network';
|
|
181
|
-
|
|
182
|
-
const getNetworkType = async () => {
|
|
183
|
-
const networkState = await Network.getNetworkStateAsync();
|
|
184
|
-
return networkState.type; // 'WIFI', 'CELLULAR', etc.
|
|
185
|
-
};
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
## Attribution Setup for Expo
|
|
189
|
-
|
|
190
|
-
Deep links work the same way, but configuration is in `app.json`:
|
|
191
|
-
|
|
192
|
-
### Test URLs (Same as React Native)
|
|
193
|
-
```typescript
|
|
194
|
-
// Test with Datalyr LYR tags
|
|
195
|
-
const lyrUrl = 'yourappscheme://open?lyr=expo_campaign&utm_source=facebook&fbclid=abc123';
|
|
196
|
-
|
|
197
|
-
// Test Facebook attribution
|
|
198
|
-
const facebookUrl = 'yourappscheme://open?utm_source=facebook&utm_campaign=summer_sale&fbclid=IwAR123abc';
|
|
199
|
-
|
|
200
|
-
// Test TikTok attribution
|
|
201
|
-
const tiktokUrl = 'yourappscheme://open?utm_source=tiktok&utm_campaign=viral_video&ttclid=tiktok123xyz';
|
|
202
|
-
|
|
203
|
-
// Test Google attribution
|
|
204
|
-
const googleUrl = 'yourappscheme://open?utm_source=google&utm_campaign=brand_search&gclid=google456def';
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
## Testing with Expo
|
|
208
|
-
|
|
209
|
-
### Development
|
|
210
|
-
```bash
|
|
211
|
-
# Start Expo development server
|
|
212
|
-
npx expo start
|
|
213
|
-
|
|
214
|
-
# Test on device/simulator
|
|
215
|
-
npx expo start --ios
|
|
216
|
-
npx expo start --android
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
### Production Testing
|
|
220
|
-
```bash
|
|
221
|
-
# Build for testing
|
|
222
|
-
eas build --platform ios --profile preview
|
|
223
|
-
eas build --platform android --profile preview
|
|
224
|
-
|
|
225
|
-
# Submit to stores
|
|
226
|
-
eas submit --platform ios
|
|
227
|
-
eas submit --platform android
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
## Expo Limitations
|
|
231
|
-
|
|
232
|
-
### What Works:
|
|
233
|
-
- Event tracking and attribution
|
|
234
|
-
- Session management
|
|
235
|
-
- Screen view tracking
|
|
236
|
-
- App lifecycle events
|
|
237
|
-
- Deep link attribution
|
|
238
|
-
- Basic device fingerprinting
|
|
239
|
-
|
|
240
|
-
### Limitations:
|
|
241
|
-
- **IDFA/GAID Collection** - Requires additional setup
|
|
242
|
-
- **Advanced Device Info** - Some properties not available in managed workflow
|
|
243
|
-
- **Carrier Information** - Not available in managed workflow
|
|
244
|
-
- **Custom Native Modules** - Not available in managed workflow
|
|
245
|
-
|
|
246
|
-
## Recommended Setup
|
|
247
|
-
|
|
248
|
-
### For Maximum Compatibility:
|
|
249
|
-
1. **Use Expo Bare Workflow** - Get full React Native CLI features
|
|
250
|
-
2. **Or use regular React Native CLI** - Best for attribution tracking
|
|
251
|
-
|
|
252
|
-
### For Managed Workflow:
|
|
253
|
-
1. **Accept some limitations** - IDFA/GAID might need additional setup
|
|
254
|
-
2. **Core attribution still works** - LYR tags, UTM params, click IDs
|
|
255
|
-
3. **Automatic events work fully** - Sessions, screen views, app lifecycle
|
|
256
|
-
|
|
257
|
-
## Expected Events in Dashboard
|
|
258
|
-
|
|
259
|
-
Events will appear in your Datalyr dashboard with `source: 'mobile_app'`:
|
|
260
|
-
|
|
261
|
-
**Automatic Events:**
|
|
262
|
-
- `session_start` - New user session
|
|
263
|
-
- `session_end` - Session ended with stats
|
|
264
|
-
- `pageviews` - Screen navigation
|
|
265
|
-
- `app_install` - First app launch with attribution
|
|
266
|
-
- `app_update` - App version changes
|
|
267
|
-
- `app_foreground`/`app_background` - App lifecycle
|
|
268
|
-
- `sdk_initialized` - SDK setup complete
|
|
269
|
-
|
|
270
|
-
**Manual Events:**
|
|
271
|
-
- Custom events from `datalyr.track()`
|
|
272
|
-
- User identification from `datalyr.identify()`
|
|
273
|
-
|
|
274
|
-
## Choosing Between Expo and React Native CLI
|
|
275
|
-
|
|
276
|
-
### Choose **React Native CLI** if:
|
|
277
|
-
- You need full IDFA/GAID support
|
|
278
|
-
- You want maximum attribution accuracy
|
|
279
|
-
- You're comfortable with native development
|
|
280
|
-
- You need custom native modules
|
|
281
|
-
|
|
282
|
-
### Choose **Expo Managed** if:
|
|
283
|
-
- You want easier development and deployment
|
|
284
|
-
- Core attribution (LYR tags, UTM, click IDs) is sufficient
|
|
285
|
-
- You're okay with some device fingerprinting limitations
|
|
286
|
-
- You prioritize development speed over maximum tracking
|
|
287
|
-
|
|
288
|
-
### Choose **Expo Bare** if:
|
|
289
|
-
- You want the best of both worlds
|
|
290
|
-
- You can use the full React Native CLI SDK
|
|
291
|
-
- You like Expo's build and deployment tools
|
|
292
|
-
|
|
293
|
-
---
|
|
294
|
-
|
|
295
|
-
**Ready to test?** Your Expo app with automatic attribution is ready!
|
|
296
|
-
|
|
297
|
-
The SDK provides 90% of the attribution value even with Expo's managed workflow limitations.
|
package/INSTALL.md
DELETED
|
@@ -1,402 +0,0 @@
|
|
|
1
|
-
# Datalyr React Native SDK - Installation Guide
|
|
2
|
-
|
|
3
|
-
## Key Features
|
|
4
|
-
|
|
5
|
-
- **Complete Attribution** - Track users from ad click to conversion
|
|
6
|
-
- **Automatic Events** - Sessions, screen views, app lifecycle
|
|
7
|
-
- **SKAdNetwork Support** - iOS 14+ attribution
|
|
8
|
-
- **Offline Support** - Queue events when offline
|
|
9
|
-
- **Deep Link Support** - Extract attribution from app launches
|
|
10
|
-
- **Privacy Compliant** - GDPR/CCPA support
|
|
11
|
-
|
|
12
|
-
## Quick Setup
|
|
13
|
-
|
|
14
|
-
### 1. Install Package
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
npm install @datalyr/react-native
|
|
18
|
-
# or
|
|
19
|
-
yarn add @datalyr/react-native
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
### 2. iOS Setup (if targeting iOS)
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
cd ios && pod install && cd ..
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
### 3. Initialize in Your App
|
|
29
|
-
|
|
30
|
-
**Basic Setup:**
|
|
31
|
-
```typescript
|
|
32
|
-
// App.tsx or your main component
|
|
33
|
-
import React, { useEffect } from 'react';
|
|
34
|
-
import { datalyr } from '@datalyr/react-native-sdk';
|
|
35
|
-
|
|
36
|
-
const App: React.FC = () => {
|
|
37
|
-
useEffect(() => {
|
|
38
|
-
initializeDatalyr();
|
|
39
|
-
}, []);
|
|
40
|
-
|
|
41
|
-
const initializeDatalyr = async () => {
|
|
42
|
-
try {
|
|
43
|
-
await datalyr.initialize({
|
|
44
|
-
workspaceId: 'ozLZblQ8hN', // Your workspace ID
|
|
45
|
-
apiKey: 'dk_your_api_key', // Required for authentication
|
|
46
|
-
debug: true,
|
|
47
|
-
enableAttribution: true, // ✅ Deep link attribution tracking
|
|
48
|
-
autoEvents: {
|
|
49
|
-
trackSessions: true, // ✅ Automatic session tracking
|
|
50
|
-
trackScreenViews: true, // ✅ Automatic screen tracking
|
|
51
|
-
trackAppUpdates: true, // ✅ App version changes
|
|
52
|
-
trackPerformance: true, // ✅ App launch time, performance
|
|
53
|
-
sessionTimeoutMs: 30 * 60 * 1000, // 30 minutes
|
|
54
|
-
},
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
// Manual events still work (but many are now automatic!)
|
|
58
|
-
await datalyr.track('app_launch');
|
|
59
|
-
|
|
60
|
-
console.log('Datalyr SDK initialized with auto-events!');
|
|
61
|
-
} catch (error) {
|
|
62
|
-
console.error('SDK init failed:', error);
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
// ... rest of your app
|
|
67
|
-
};
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
**SKAdNetwork Setup (iOS 14+ Attribution):**
|
|
71
|
-
```typescript
|
|
72
|
-
// For iOS attribution competing with AppsFlyer/Adjust
|
|
73
|
-
import React, { useEffect } from 'react';
|
|
74
|
-
import { Datalyr } from '@datalyr/react-native-sdk';
|
|
75
|
-
|
|
76
|
-
const App: React.FC = () => {
|
|
77
|
-
useEffect(() => {
|
|
78
|
-
initializeDatalyrWithSKAdNetwork();
|
|
79
|
-
}, []);
|
|
80
|
-
|
|
81
|
-
const initializeDatalyrWithSKAdNetwork = async () => {
|
|
82
|
-
try {
|
|
83
|
-
await Datalyr.initialize({
|
|
84
|
-
workspaceId: 'your-workspace-id',
|
|
85
|
-
apiKey: 'dk_your_api_key',
|
|
86
|
-
skadTemplate: 'ecommerce', // Choose: 'ecommerce', 'gaming', 'subscription'
|
|
87
|
-
debug: true,
|
|
88
|
-
enableAttribution: true,
|
|
89
|
-
autoEvents: {
|
|
90
|
-
trackSessions: true,
|
|
91
|
-
trackScreenViews: true,
|
|
92
|
-
},
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
console.log('Datalyr SDK initialized with SKAdNetwork!');
|
|
96
|
-
} catch (error) {
|
|
97
|
-
console.error('SDK init failed:', error);
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
// ... rest of your app
|
|
102
|
-
};
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### 5. Test the Integration
|
|
106
|
-
|
|
107
|
-
```typescript
|
|
108
|
-
// Test tracking events
|
|
109
|
-
const testTracking = async () => {
|
|
110
|
-
// Track a purchase
|
|
111
|
-
await datalyr.track('purchase', {
|
|
112
|
-
value: 29.99,
|
|
113
|
-
currency: 'USD',
|
|
114
|
-
item_id: 'test_product'
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
// Identify a user
|
|
118
|
-
await datalyr.identify('user_123', {
|
|
119
|
-
email: 'test@example.com',
|
|
120
|
-
name: 'Test User'
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
// Track screen view
|
|
124
|
-
await datalyr.screen('home_screen');
|
|
125
|
-
};
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
## Configuration Options
|
|
129
|
-
|
|
130
|
-
```typescript
|
|
131
|
-
await datalyr.initialize({
|
|
132
|
-
workspaceId: 'your-workspace-id', // Required
|
|
133
|
-
apiKey: 'dk_your_api_key', // Required for authentication
|
|
134
|
-
debug: true, // Enable debug logs
|
|
135
|
-
endpoint: 'custom-endpoint', // Optional custom endpoint
|
|
136
|
-
maxRetries: 3, // Network retry attempts
|
|
137
|
-
retryDelay: 1000, // Retry delay in ms
|
|
138
|
-
batchSize: 10, // Events per batch
|
|
139
|
-
flushInterval: 10000, // Auto-flush interval in ms
|
|
140
|
-
maxQueueSize: 100, // Max offline queue size
|
|
141
|
-
|
|
142
|
-
// 🚀 NEW: SKAdNetwork Support (iOS 14+ Attribution)
|
|
143
|
-
skadTemplate: 'ecommerce', // Choose: 'ecommerce', 'gaming', 'subscription'
|
|
144
|
-
|
|
145
|
-
// 🚀 NEW: Automatic Events (Like Mixpanel)
|
|
146
|
-
autoEvents: {
|
|
147
|
-
trackSessions: true, // Session start/end tracking
|
|
148
|
-
trackScreenViews: true, // Automatic screen view events
|
|
149
|
-
trackAppUpdates: true, // App version change detection
|
|
150
|
-
trackPerformance: true, // App launch performance tracking
|
|
151
|
-
sessionTimeoutMs: 30 * 60 * 1000, // Session timeout (30 minutes)
|
|
152
|
-
},
|
|
153
|
-
});
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
## Platform Requirements
|
|
157
|
-
|
|
158
|
-
- **React Native**: >= 0.60.0
|
|
159
|
-
- **iOS**: >= 11.0
|
|
160
|
-
- **Android**: >= API level 21
|
|
161
|
-
|
|
162
|
-
## Framework Compatibility
|
|
163
|
-
|
|
164
|
-
| Framework | Compatibility | Install Guide |
|
|
165
|
-
|-----------|---------------|---------------|
|
|
166
|
-
| **React Native CLI** | ✅ Full Support | This guide |
|
|
167
|
-
| **Expo Bare Workflow** | ✅ Full Support | This guide |
|
|
168
|
-
| **Expo Managed Workflow** | ✅ Supported* | [EXPO_INSTALL.md](./EXPO_INSTALL.md) |
|
|
169
|
-
| **Expo Go** | ⚠️ Limited | Use managed workflow |
|
|
170
|
-
|
|
171
|
-
*\*Expo managed workflow has some limitations (IDFA/GAID collection requires additional setup)*
|
|
172
|
-
|
|
173
|
-
**📖 For Expo users:** See [EXPO_INSTALL.md](./EXPO_INSTALL.md) for Expo-specific setup instructions.
|
|
174
|
-
|
|
175
|
-
## Setting Up Attribution
|
|
176
|
-
|
|
177
|
-
### 1. Configure Deep Links
|
|
178
|
-
|
|
179
|
-
Add URL scheme to your app to handle attribution links:
|
|
180
|
-
|
|
181
|
-
**iOS (ios/YourApp/Info.plist):**
|
|
182
|
-
```xml
|
|
183
|
-
<key>CFBundleURLTypes</key>
|
|
184
|
-
<array>
|
|
185
|
-
<dict>
|
|
186
|
-
<key>CFBundleURLName</key>
|
|
187
|
-
<string>your.app.identifier</string>
|
|
188
|
-
<key>CFBundleURLSchemes</key>
|
|
189
|
-
<array>
|
|
190
|
-
<string>yourappscheme</string>
|
|
191
|
-
</array>
|
|
192
|
-
</dict>
|
|
193
|
-
</array>
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
**Android (android/app/src/main/AndroidManifest.xml):**
|
|
197
|
-
```xml
|
|
198
|
-
<activity
|
|
199
|
-
android:name=".MainActivity"
|
|
200
|
-
android:exported="true"
|
|
201
|
-
android:launchMode="singleTop">
|
|
202
|
-
|
|
203
|
-
<intent-filter android:autoVerify="true">
|
|
204
|
-
<action android:name="android.intent.action.VIEW" />
|
|
205
|
-
<category android:name="android.intent.category.DEFAULT" />
|
|
206
|
-
<category android:name="android.intent.category.BROWSABLE" />
|
|
207
|
-
<data android:scheme="yourappscheme" />
|
|
208
|
-
</intent-filter>
|
|
209
|
-
</activity>
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
### 2. Test Attribution
|
|
213
|
-
|
|
214
|
-
```typescript
|
|
215
|
-
// Test with Datalyr LYR tags (RECOMMENDED!)
|
|
216
|
-
const lyrUrl = 'yourappscheme://open?lyr=mobile_campaign_q4&utm_source=facebook&utm_medium=paid_social&utm_campaign=summer_sale&fbclid=IwAR123abc';
|
|
217
|
-
|
|
218
|
-
// Test Facebook attribution
|
|
219
|
-
const facebookUrl = 'yourappscheme://open?utm_source=facebook&utm_medium=paid_social&utm_campaign=summer_sale&fbclid=IwAR123abc&lyr=fb_summer_2024';
|
|
220
|
-
|
|
221
|
-
// Test TikTok attribution
|
|
222
|
-
const tiktokUrl = 'yourappscheme://open?utm_source=tiktok&utm_medium=video&utm_campaign=viral_video&ttclid=tiktok123xyz&lyr=tt_viral_campaign';
|
|
223
|
-
|
|
224
|
-
// Test Google attribution
|
|
225
|
-
const googleUrl = 'yourappscheme://open?utm_source=google&utm_medium=search&utm_campaign=brand_search&gclid=google456def&lyr=google_brand_search';
|
|
226
|
-
|
|
227
|
-
// Test Partner attribution
|
|
228
|
-
const partnerUrl = 'yourappscheme://open?utm_source=partner&partner_id=partner123&affiliate_id=aff456&lyr=partner_campaign_q4';
|
|
229
|
-
|
|
230
|
-
// Get attribution data
|
|
231
|
-
const attributionData = datalyr.getAttributionData();
|
|
232
|
-
console.log('Attribution:', attributionData);
|
|
233
|
-
/*
|
|
234
|
-
Expected output:
|
|
235
|
-
{
|
|
236
|
-
lyr: "mobile_campaign_q4",
|
|
237
|
-
utm_source: "facebook",
|
|
238
|
-
campaign_source: "facebook",
|
|
239
|
-
utm_campaign: "summer_sale",
|
|
240
|
-
campaign_name: "summer_sale",
|
|
241
|
-
fbclid: "IwAR123abc",
|
|
242
|
-
install_time: "2024-01-01T00:00:00Z"
|
|
243
|
-
}
|
|
244
|
-
*/
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
## Testing Events
|
|
248
|
-
|
|
249
|
-
After setup, events will appear in your Datalyr dashboard at:
|
|
250
|
-
`https://app.datalyr.com/dashboard/ozLZblQ8hN`
|
|
251
|
-
|
|
252
|
-
Look for events with `source: 'mobile_app'` to confirm mobile tracking is working.
|
|
253
|
-
|
|
254
|
-
**Key Events to Look For:**
|
|
255
|
-
|
|
256
|
-
**🔥 Automatic Events (No Code Required!):**
|
|
257
|
-
- `session_start` - User starts a new session (automatic)
|
|
258
|
-
- `session_end` - User ends session with duration/stats (automatic)
|
|
259
|
-
- `pageviews` - User navigates between screens (automatic)
|
|
260
|
-
- `app_install` - First time app opens with attribution (automatic)
|
|
261
|
-
- `app_update` - App version changes (automatic)
|
|
262
|
-
- `app_foreground` - App becomes active (automatic)
|
|
263
|
-
- `app_background` - App goes to background (automatic)
|
|
264
|
-
- `app_launch_performance` - App startup timing (automatic)
|
|
265
|
-
- `sdk_initialized` - SDK successfully initialized (automatic)
|
|
266
|
-
|
|
267
|
-
**📱 Manual Events (When You Call Them):**
|
|
268
|
-
- Custom events you track with `datalyr.track()`
|
|
269
|
-
- User identification with `datalyr.identify()`
|
|
270
|
-
- Manual screen views with `datalyr.screen()`
|
|
271
|
-
|
|
272
|
-
## Debugging
|
|
273
|
-
|
|
274
|
-
```typescript
|
|
275
|
-
// Check SDK status
|
|
276
|
-
const status = datalyr.getStatus();
|
|
277
|
-
console.log('SDK Status:', status);
|
|
278
|
-
|
|
279
|
-
// Manually flush events
|
|
280
|
-
await datalyr.flush();
|
|
281
|
-
|
|
282
|
-
// Enable debug mode
|
|
283
|
-
await datalyr.initialize({
|
|
284
|
-
workspaceId: 'your-workspace-id',
|
|
285
|
-
debug: true // This will show detailed logs
|
|
286
|
-
});
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
## Common Issues
|
|
290
|
-
|
|
291
|
-
1. **Events not appearing**: Check debug logs and network connectivity
|
|
292
|
-
2. **Build errors**: Ensure all dependencies are installed and linked
|
|
293
|
-
3. **iOS build issues**: Run `cd ios && pod install`
|
|
294
|
-
4. **Android issues**: Check that your minSdkVersion is >= 21
|
|
295
|
-
|
|
296
|
-
## Automatic Events
|
|
297
|
-
|
|
298
|
-
Want to see all the automatic events in action? Check out `auto-events-example.tsx` for a live demo that shows:
|
|
299
|
-
|
|
300
|
-
- Real-time session tracking with duration and screen counts
|
|
301
|
-
- Automatic screen view detection as you navigate
|
|
302
|
-
- App lifecycle events (foreground/background)
|
|
303
|
-
- Revenue event tracking for purchases
|
|
304
|
-
- Session management and timeout handling
|
|
305
|
-
|
|
306
|
-
```typescript
|
|
307
|
-
// Get current session info
|
|
308
|
-
const session = datalyr.getCurrentSession();
|
|
309
|
-
console.log('Current session:', session);
|
|
310
|
-
// Output: { sessionId: 'sess_123', startTime: 1640995200000, screenViews: 5, events: 12 }
|
|
311
|
-
|
|
312
|
-
// Manual revenue tracking (also triggers automatic revenue_event)
|
|
313
|
-
await datalyr.trackRevenue('purchase', {
|
|
314
|
-
product_id: 'premium_plan',
|
|
315
|
-
price: 9.99,
|
|
316
|
-
currency: 'USD',
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
// Force end session for testing
|
|
320
|
-
await datalyr.endSession();
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
## Next Steps
|
|
324
|
-
|
|
325
|
-
- See `example.tsx` for basic integration example
|
|
326
|
-
- See `auto-events-example.tsx` for automatic events demo
|
|
327
|
-
- Check your Datalyr dashboard to verify events are coming through
|
|
328
|
-
- Set up attribution tracking for your ad campaigns
|
|
329
|
-
- Configure conversion events for your key user actions
|
|
330
|
-
|
|
331
|
-
---
|
|
332
|
-
|
|
333
|
-
## SKAdNetwork Setup (iOS Attribution)
|
|
334
|
-
|
|
335
|
-
### **1. Add Native Bridge (React Native CLI/Expo Bare)**
|
|
336
|
-
|
|
337
|
-
Create `ios/YourApp/DatalyrSKAdNetwork.m`:
|
|
338
|
-
```objc
|
|
339
|
-
#import <React/RCTBridgeModule.h>
|
|
340
|
-
#import <StoreKit/StoreKit.h>
|
|
341
|
-
|
|
342
|
-
@interface DatalyrSKAdNetwork : NSObject <RCTBridgeModule>
|
|
343
|
-
@end
|
|
344
|
-
|
|
345
|
-
@implementation DatalyrSKAdNetwork
|
|
346
|
-
|
|
347
|
-
RCT_EXPORT_MODULE();
|
|
348
|
-
|
|
349
|
-
RCT_EXPORT_METHOD(updateConversionValue:(NSInteger)value
|
|
350
|
-
resolve:(RCTPromiseResolveBlock)resolve
|
|
351
|
-
reject:(RCTPromiseRejectBlock)reject) {
|
|
352
|
-
if (@available(iOS 14.0, *)) {
|
|
353
|
-
@try {
|
|
354
|
-
[SKAdNetwork updateConversionValue:value];
|
|
355
|
-
resolve(@(YES));
|
|
356
|
-
} @catch (NSException *exception) {
|
|
357
|
-
reject(@"skadnetwork_error", exception.reason, nil);
|
|
358
|
-
}
|
|
359
|
-
} else {
|
|
360
|
-
reject(@"ios_version_error", @"SKAdNetwork requires iOS 14.0+", nil);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
@end
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
### **2. Track Events with SKAdNetwork**
|
|
368
|
-
|
|
369
|
-
```typescript
|
|
370
|
-
import { Datalyr } from '@datalyr/react-native-sdk';
|
|
371
|
-
|
|
372
|
-
// Track events with automatic conversion value encoding
|
|
373
|
-
await Datalyr.trackPurchase(29.99, 'USD', 'premium_plan');
|
|
374
|
-
await Datalyr.trackWithSKAdNetwork('add_to_cart', { product_id: 'shirt_001' });
|
|
375
|
-
await Datalyr.trackWithSKAdNetwork('level_complete', { level: 5, score: 1250 });
|
|
376
|
-
|
|
377
|
-
// Test conversion values (doesn't send to Apple)
|
|
378
|
-
const value = Datalyr.getConversionValue('purchase', { revenue: 29.99 });
|
|
379
|
-
console.log('Conversion value:', value); // Example: 5
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
### **3. Industry Templates**
|
|
383
|
-
|
|
384
|
-
Choose the template that best fits your app:
|
|
385
|
-
|
|
386
|
-
**E-commerce (`skadTemplate: 'ecommerce'`):**
|
|
387
|
-
- Optimized for: purchase, add_to_cart, begin_checkout, signup, subscribe, view_item
|
|
388
|
-
- Revenue encoding: 8 tiers from $0-1 to $250+
|
|
389
|
-
|
|
390
|
-
**Gaming (`skadTemplate: 'gaming'`):**
|
|
391
|
-
- Optimized for: level_complete, tutorial_complete, purchase, achievement_unlocked, session_start, ad_watched
|
|
392
|
-
- Revenue encoding for in-app purchases
|
|
393
|
-
|
|
394
|
-
**Subscription (`skadTemplate: 'subscription'`):**
|
|
395
|
-
- Optimized for: trial_start, subscribe, upgrade, cancel, signup, payment_method_added
|
|
396
|
-
- Revenue encoding for subscription plans
|
|
397
|
-
|
|
398
|
-
---
|
|
399
|
-
|
|
400
|
-
**Ready to test? Your mobile attribution + automatic events + SKAdNetwork are now live! 🚀**
|
|
401
|
-
|
|
402
|
-
*Compete with AppsFlyer/Adjust at 90% cost savings while getting Mixpanel-style automatic events!*
|