insert-affiliate-react-native-sdk 1.8.0 → 1.10.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/dist/DeepLinkIapProvider.d.ts +7 -1
- package/dist/DeepLinkIapProvider.js +209 -17
- package/dist/index.d.ts +1 -1
- package/dist/useDeepLinkIapProvider.d.ts +2 -1
- package/dist/useDeepLinkIapProvider.js +2 -1
- package/docs/deep-linking-appsflyer.md +364 -0
- package/docs/deep-linking-branch.md +330 -0
- package/docs/dynamic-offer-codes.md +369 -0
- package/package.json +1 -1
- package/readme.md +600 -982
- package/src/DeepLinkIapProvider.tsx +256 -28
- package/src/index.ts +1 -1
- package/src/useDeepLinkIapProvider.tsx +2 -0
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
# AppsFlyer Deep Linking Integration
|
|
2
|
+
|
|
3
|
+
This guide shows how to integrate InsertAffiliateReactNative SDK with AppsFlyer for deep linking attribution.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- [AppsFlyer SDK for React Native](https://dev.appsflyer.com/hc/docs/react-native-plugin) installed and configured
|
|
8
|
+
- Create an AppsFlyer OneLink and provide it to affiliates via the [Insert Affiliate dashboard](https://app.insertaffiliate.com/affiliates)
|
|
9
|
+
|
|
10
|
+
## Platform Setup
|
|
11
|
+
|
|
12
|
+
Complete the deep linking setup for AppsFlyer by following their official documentation:
|
|
13
|
+
- [AppsFlyer Deferred Deep Link Integration Guide](https://dev.appsflyer.com/hc/docs/deeplinkintegrate)
|
|
14
|
+
|
|
15
|
+
This covers all platform-specific configurations including:
|
|
16
|
+
- iOS: Info.plist configuration, AppDelegate setup, and universal links
|
|
17
|
+
- Android: AndroidManifest.xml intent filters, MainActivity setup, and App Links
|
|
18
|
+
- Testing and troubleshooting for both platforms
|
|
19
|
+
|
|
20
|
+
## Integration Examples
|
|
21
|
+
|
|
22
|
+
Choose the example that matches your IAP verification platform:
|
|
23
|
+
|
|
24
|
+
### Example with RevenueCat
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
import React, { useEffect } from 'react';
|
|
28
|
+
import { AppRegistry, Platform } from 'react-native';
|
|
29
|
+
import appsFlyer from 'react-native-appsflyer';
|
|
30
|
+
import Purchases from 'react-native-purchases';
|
|
31
|
+
import { useDeepLinkIapProvider, DeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
|
|
32
|
+
import App from './App';
|
|
33
|
+
import { name as appName } from './app.json';
|
|
34
|
+
|
|
35
|
+
const DeepLinkHandler = () => {
|
|
36
|
+
const { setInsertAffiliateIdentifier, isInitialized } = useDeepLinkIapProvider();
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (!isInitialized) return;
|
|
40
|
+
|
|
41
|
+
// Initialize AppsFlyer
|
|
42
|
+
const initAppsFlyer = async () => {
|
|
43
|
+
try {
|
|
44
|
+
const initOptions = {
|
|
45
|
+
devKey: 'YOUR_APPSFLYER_DEV_KEY',
|
|
46
|
+
isDebug: true,
|
|
47
|
+
appId: Platform.OS === 'ios' ? 'YOUR_IOS_APP_ID' : 'YOUR_ANDROID_PACKAGE_NAME',
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
await appsFlyer.initSdk(initOptions);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error('AppsFlyer initialization error:', error);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// Handle deep link data
|
|
57
|
+
const handleDeepLink = async (deepLinkData) => {
|
|
58
|
+
if (deepLinkData && deepLinkData.data) {
|
|
59
|
+
const referringLink = deepLinkData.data.link || deepLinkData.data.deep_link_value;
|
|
60
|
+
|
|
61
|
+
if (referringLink) {
|
|
62
|
+
try {
|
|
63
|
+
const insertAffiliateIdentifier = await setInsertAffiliateIdentifier(referringLink);
|
|
64
|
+
|
|
65
|
+
if (insertAffiliateIdentifier) {
|
|
66
|
+
await Purchases.setAttributes({ "insert_affiliate": insertAffiliateIdentifier });
|
|
67
|
+
}
|
|
68
|
+
} catch (err) {
|
|
69
|
+
console.error('Error setting affiliate identifier:', err);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// Listen for all deep link types
|
|
76
|
+
appsFlyer.onDeepLink(handleDeepLink);
|
|
77
|
+
appsFlyer.onAppOpenAttribution(handleDeepLink);
|
|
78
|
+
appsFlyer.onInstallConversionData(handleDeepLink);
|
|
79
|
+
|
|
80
|
+
initAppsFlyer();
|
|
81
|
+
}, [setInsertAffiliateIdentifier, isInitialized]);
|
|
82
|
+
|
|
83
|
+
return <App />;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const RootComponent = () => {
|
|
87
|
+
return (
|
|
88
|
+
<DeepLinkIapProvider>
|
|
89
|
+
<DeepLinkHandler />
|
|
90
|
+
</DeepLinkIapProvider>
|
|
91
|
+
);
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
AppRegistry.registerComponent(appName, () => RootComponent);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Replace the following:**
|
|
98
|
+
- `YOUR_APPSFLYER_DEV_KEY` with your AppsFlyer Dev Key
|
|
99
|
+
- `YOUR_IOS_APP_ID` with your iOS App ID (numbers only, e.g., "123456789")
|
|
100
|
+
- `YOUR_ANDROID_PACKAGE_NAME` with your Android package name
|
|
101
|
+
|
|
102
|
+
### Example with Adapty
|
|
103
|
+
|
|
104
|
+
```javascript
|
|
105
|
+
import React, { useEffect } from 'react';
|
|
106
|
+
import { AppRegistry, Platform } from 'react-native';
|
|
107
|
+
import appsFlyer from 'react-native-appsflyer';
|
|
108
|
+
import { adapty } from 'react-native-adapty';
|
|
109
|
+
import { useDeepLinkIapProvider, DeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
|
|
110
|
+
import App from './App';
|
|
111
|
+
import { name as appName } from './app.json';
|
|
112
|
+
|
|
113
|
+
const DeepLinkHandler = () => {
|
|
114
|
+
const { setInsertAffiliateIdentifier, isInitialized } = useDeepLinkIapProvider();
|
|
115
|
+
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
if (!isInitialized) return;
|
|
118
|
+
|
|
119
|
+
const initAppsFlyer = async () => {
|
|
120
|
+
try {
|
|
121
|
+
const initOptions = {
|
|
122
|
+
devKey: 'YOUR_APPSFLYER_DEV_KEY',
|
|
123
|
+
isDebug: true,
|
|
124
|
+
appId: Platform.OS === 'ios' ? 'YOUR_IOS_APP_ID' : 'YOUR_ANDROID_PACKAGE_NAME',
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
await appsFlyer.initSdk(initOptions);
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error('AppsFlyer initialization error:', error);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const handleDeepLink = async (deepLinkData) => {
|
|
134
|
+
if (deepLinkData && deepLinkData.data) {
|
|
135
|
+
const referringLink = deepLinkData.data.link || deepLinkData.data.deep_link_value;
|
|
136
|
+
|
|
137
|
+
if (referringLink) {
|
|
138
|
+
try {
|
|
139
|
+
const insertAffiliateIdentifier = await setInsertAffiliateIdentifier(referringLink);
|
|
140
|
+
|
|
141
|
+
if (insertAffiliateIdentifier) {
|
|
142
|
+
await adapty.updateProfile({
|
|
143
|
+
codableCustomAttributes: {
|
|
144
|
+
insert_affiliate: insertAffiliateIdentifier,
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
} catch (err) {
|
|
149
|
+
console.error('Error setting affiliate identifier:', err);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
appsFlyer.onDeepLink(handleDeepLink);
|
|
156
|
+
appsFlyer.onAppOpenAttribution(handleDeepLink);
|
|
157
|
+
appsFlyer.onInstallConversionData(handleDeepLink);
|
|
158
|
+
|
|
159
|
+
initAppsFlyer();
|
|
160
|
+
}, [setInsertAffiliateIdentifier, isInitialized]);
|
|
161
|
+
|
|
162
|
+
return <App />;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const RootComponent = () => {
|
|
166
|
+
return (
|
|
167
|
+
<DeepLinkIapProvider>
|
|
168
|
+
<DeepLinkHandler />
|
|
169
|
+
</DeepLinkIapProvider>
|
|
170
|
+
);
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
AppRegistry.registerComponent(appName, () => RootComponent);
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Example with Apphud
|
|
177
|
+
|
|
178
|
+
```javascript
|
|
179
|
+
import React, { useEffect } from 'react';
|
|
180
|
+
import { AppRegistry, Platform } from 'react-native';
|
|
181
|
+
import appsFlyer from 'react-native-appsflyer';
|
|
182
|
+
import Apphud from 'react-native-apphud';
|
|
183
|
+
import { useDeepLinkIapProvider, DeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
|
|
184
|
+
import App from './App';
|
|
185
|
+
import { name as appName } from './app.json';
|
|
186
|
+
|
|
187
|
+
const DeepLinkHandler = () => {
|
|
188
|
+
const { setInsertAffiliateIdentifier, isInitialized } = useDeepLinkIapProvider();
|
|
189
|
+
|
|
190
|
+
useEffect(() => {
|
|
191
|
+
if (!isInitialized) return;
|
|
192
|
+
|
|
193
|
+
const initAppsFlyer = async () => {
|
|
194
|
+
try {
|
|
195
|
+
const initOptions = {
|
|
196
|
+
devKey: 'YOUR_APPSFLYER_DEV_KEY',
|
|
197
|
+
isDebug: true,
|
|
198
|
+
appId: Platform.OS === 'ios' ? 'YOUR_IOS_APP_ID' : 'YOUR_ANDROID_PACKAGE_NAME',
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
await appsFlyer.initSdk(initOptions);
|
|
202
|
+
} catch (error) {
|
|
203
|
+
console.error('AppsFlyer initialization error:', error);
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
const handleDeepLink = async (deepLinkData) => {
|
|
208
|
+
if (deepLinkData && deepLinkData.data) {
|
|
209
|
+
const referringLink = deepLinkData.data.link || deepLinkData.data.deep_link_value;
|
|
210
|
+
|
|
211
|
+
if (referringLink) {
|
|
212
|
+
try {
|
|
213
|
+
const insertAffiliateIdentifier = await setInsertAffiliateIdentifier(referringLink);
|
|
214
|
+
|
|
215
|
+
if (insertAffiliateIdentifier) {
|
|
216
|
+
await Apphud.setUserProperty("insert_affiliate", insertAffiliateIdentifier, false);
|
|
217
|
+
}
|
|
218
|
+
} catch (err) {
|
|
219
|
+
console.error('Error setting affiliate identifier:', err);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
appsFlyer.onDeepLink(handleDeepLink);
|
|
226
|
+
appsFlyer.onAppOpenAttribution(handleDeepLink);
|
|
227
|
+
appsFlyer.onInstallConversionData(handleDeepLink);
|
|
228
|
+
|
|
229
|
+
initAppsFlyer();
|
|
230
|
+
}, [setInsertAffiliateIdentifier, isInitialized]);
|
|
231
|
+
|
|
232
|
+
return <App />;
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
const RootComponent = () => {
|
|
236
|
+
return (
|
|
237
|
+
<DeepLinkIapProvider>
|
|
238
|
+
<DeepLinkHandler />
|
|
239
|
+
</DeepLinkIapProvider>
|
|
240
|
+
);
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
AppRegistry.registerComponent(appName, () => RootComponent);
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Example with Iaptic / Store Direct Integration
|
|
247
|
+
|
|
248
|
+
```javascript
|
|
249
|
+
import React, { useEffect } from 'react';
|
|
250
|
+
import { AppRegistry, Platform } from 'react-native';
|
|
251
|
+
import appsFlyer from 'react-native-appsflyer';
|
|
252
|
+
import { useDeepLinkIapProvider, DeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
|
|
253
|
+
import App from './App';
|
|
254
|
+
import { name as appName } from './app.json';
|
|
255
|
+
|
|
256
|
+
const DeepLinkHandler = () => {
|
|
257
|
+
const { setInsertAffiliateIdentifier, isInitialized } = useDeepLinkIapProvider();
|
|
258
|
+
|
|
259
|
+
useEffect(() => {
|
|
260
|
+
if (!isInitialized) return;
|
|
261
|
+
|
|
262
|
+
const initAppsFlyer = async () => {
|
|
263
|
+
try {
|
|
264
|
+
const initOptions = {
|
|
265
|
+
devKey: 'YOUR_APPSFLYER_DEV_KEY',
|
|
266
|
+
isDebug: true,
|
|
267
|
+
appId: Platform.OS === 'ios' ? 'YOUR_IOS_APP_ID' : 'YOUR_ANDROID_PACKAGE_NAME',
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
await appsFlyer.initSdk(initOptions);
|
|
271
|
+
} catch (error) {
|
|
272
|
+
console.error('AppsFlyer initialization error:', error);
|
|
273
|
+
}
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
const handleDeepLink = async (deepLinkData) => {
|
|
277
|
+
if (deepLinkData && deepLinkData.data) {
|
|
278
|
+
const referringLink = deepLinkData.data.link || deepLinkData.data.deep_link_value;
|
|
279
|
+
|
|
280
|
+
if (referringLink) {
|
|
281
|
+
try {
|
|
282
|
+
await setInsertAffiliateIdentifier(referringLink);
|
|
283
|
+
// Affiliate identifier is stored automatically for Iaptic/direct store integration
|
|
284
|
+
} catch (err) {
|
|
285
|
+
console.error('Error setting affiliate identifier:', err);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
appsFlyer.onDeepLink(handleDeepLink);
|
|
292
|
+
appsFlyer.onAppOpenAttribution(handleDeepLink);
|
|
293
|
+
appsFlyer.onInstallConversionData(handleDeepLink);
|
|
294
|
+
|
|
295
|
+
initAppsFlyer();
|
|
296
|
+
}, [setInsertAffiliateIdentifier, isInitialized]);
|
|
297
|
+
|
|
298
|
+
return <App />;
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
const RootComponent = () => {
|
|
302
|
+
return (
|
|
303
|
+
<DeepLinkIapProvider>
|
|
304
|
+
<DeepLinkHandler />
|
|
305
|
+
</DeepLinkIapProvider>
|
|
306
|
+
);
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
AppRegistry.registerComponent(appName, () => RootComponent);
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Deep Link Listener Types
|
|
313
|
+
|
|
314
|
+
AppsFlyer provides three types of deep link callbacks:
|
|
315
|
+
|
|
316
|
+
| Callback | When It Fires | Use Case |
|
|
317
|
+
|----------|---------------|----------|
|
|
318
|
+
| `onDeepLink` | App opened via deep link (app already installed) | Direct attribution |
|
|
319
|
+
| `onAppOpenAttribution` | App opened via deep link with attribution data | Re-engagement campaigns |
|
|
320
|
+
| `onInstallConversionData` | First app launch after install | Deferred deep linking |
|
|
321
|
+
|
|
322
|
+
For comprehensive affiliate tracking, we recommend listening to all three as shown in the examples above.
|
|
323
|
+
|
|
324
|
+
## Testing
|
|
325
|
+
|
|
326
|
+
Test your AppsFlyer deep link integration:
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
# Test with your OneLink URL (iOS Simulator)
|
|
330
|
+
xcrun simctl openurl booted "https://your-app.onelink.me/abc123"
|
|
331
|
+
|
|
332
|
+
# Test with your OneLink URL (Android Emulator)
|
|
333
|
+
adb shell am start -W -a android.intent.action.VIEW -d "https://your-app.onelink.me/abc123"
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## Troubleshooting
|
|
337
|
+
|
|
338
|
+
**Problem:** Attribution callback not firing
|
|
339
|
+
- **Solution:** Ensure AppsFlyer SDK is initialized with correct dev key and app ID
|
|
340
|
+
- Check AppsFlyer dashboard to verify OneLink is active
|
|
341
|
+
- Verify `isInitialized` is `true` before setting up listeners
|
|
342
|
+
|
|
343
|
+
**Problem:** Deep link parameters not captured
|
|
344
|
+
- **Solution:** Verify deep link contains correct parameters in AppsFlyer dashboard
|
|
345
|
+
- Check Info.plist has correct URL schemes and associated domains (iOS)
|
|
346
|
+
- Check AndroidManifest.xml has correct intent filters (Android)
|
|
347
|
+
|
|
348
|
+
**Problem:** Deferred deep linking not working
|
|
349
|
+
- **Solution:** Make sure `onInstallConversionData` listener is set up
|
|
350
|
+
- Test with a fresh app install (uninstall/reinstall)
|
|
351
|
+
- Verify AppsFlyer's "Deferred Deep Linking" is enabled in dashboard
|
|
352
|
+
|
|
353
|
+
**Problem:** `deep_link_value` is undefined
|
|
354
|
+
- **Solution:** Ensure you're accessing the correct property path in the callback data
|
|
355
|
+
- Log the full `deepLinkData` object to see available fields
|
|
356
|
+
|
|
357
|
+
## Next Steps
|
|
358
|
+
|
|
359
|
+
After completing AppsFlyer integration:
|
|
360
|
+
1. Test deep link attribution with a test affiliate link
|
|
361
|
+
2. Verify affiliate identifier is stored correctly
|
|
362
|
+
3. Make a test purchase to confirm tracking works end-to-end
|
|
363
|
+
|
|
364
|
+
[Back to Main README](../readme.md)
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
# Branch.io Deep Linking Integration
|
|
2
|
+
|
|
3
|
+
This guide shows how to integrate InsertAffiliateReactNative SDK with Branch.io for deep linking attribution.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- [Branch SDK for React Native](https://help.branch.io/developers-hub/docs/react-native) installed and configured
|
|
8
|
+
- Create a Branch deep link and provide it to affiliates via the [Insert Affiliate dashboard](https://app.insertaffiliate.com/affiliates)
|
|
9
|
+
|
|
10
|
+
## Platform Setup
|
|
11
|
+
|
|
12
|
+
Complete the deep linking setup for Branch by following their official documentation:
|
|
13
|
+
- [Branch React Native SDK Integration Guide](https://help.branch.io/developers-hub/docs/react-native)
|
|
14
|
+
|
|
15
|
+
This covers:
|
|
16
|
+
- iOS: Info.plist configuration, AppDelegate setup, and universal links
|
|
17
|
+
- Android: AndroidManifest.xml intent filters and App Links
|
|
18
|
+
- Testing and troubleshooting
|
|
19
|
+
|
|
20
|
+
## Integration Examples
|
|
21
|
+
|
|
22
|
+
Choose the example that matches your IAP verification platform:
|
|
23
|
+
|
|
24
|
+
### Example with RevenueCat
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
import React, { useEffect } from 'react';
|
|
28
|
+
import { AppRegistry } from 'react-native';
|
|
29
|
+
import branch from 'react-native-branch';
|
|
30
|
+
import Purchases from 'react-native-purchases';
|
|
31
|
+
import { useDeepLinkIapProvider, DeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
|
|
32
|
+
import App from './App';
|
|
33
|
+
import { name as appName } from './app.json';
|
|
34
|
+
|
|
35
|
+
const DeepLinkHandler = () => {
|
|
36
|
+
const { setInsertAffiliateIdentifier } = useDeepLinkIapProvider();
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
const branchSubscription = branch.subscribe(async ({ error, params }) => {
|
|
40
|
+
if (error) {
|
|
41
|
+
console.error('Error from Branch:', error);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (params['+clicked_branch_link']) {
|
|
46
|
+
const referringLink = params['~referring_link'];
|
|
47
|
+
if (referringLink) {
|
|
48
|
+
try {
|
|
49
|
+
const insertAffiliateIdentifier = await setInsertAffiliateIdentifier(referringLink);
|
|
50
|
+
|
|
51
|
+
if (insertAffiliateIdentifier) {
|
|
52
|
+
await Purchases.setAttributes({ "insert_affiliate": insertAffiliateIdentifier });
|
|
53
|
+
}
|
|
54
|
+
} catch (err) {
|
|
55
|
+
console.error('Error setting affiliate identifier:', err);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
return () => {
|
|
62
|
+
branchSubscription();
|
|
63
|
+
};
|
|
64
|
+
}, [setInsertAffiliateIdentifier]);
|
|
65
|
+
|
|
66
|
+
return <App />;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const RootComponent = () => {
|
|
70
|
+
return (
|
|
71
|
+
<DeepLinkIapProvider>
|
|
72
|
+
<DeepLinkHandler />
|
|
73
|
+
</DeepLinkIapProvider>
|
|
74
|
+
);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
AppRegistry.registerComponent(appName, () => RootComponent);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Example with Adapty
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
import React, { useEffect } from 'react';
|
|
84
|
+
import { AppRegistry } from 'react-native';
|
|
85
|
+
import branch from 'react-native-branch';
|
|
86
|
+
import { adapty } from 'react-native-adapty';
|
|
87
|
+
import { useDeepLinkIapProvider, DeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
|
|
88
|
+
import App from './App';
|
|
89
|
+
import { name as appName } from './app.json';
|
|
90
|
+
|
|
91
|
+
const DeepLinkHandler = () => {
|
|
92
|
+
const { setInsertAffiliateIdentifier } = useDeepLinkIapProvider();
|
|
93
|
+
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
const branchSubscription = branch.subscribe(async ({ error, params }) => {
|
|
96
|
+
if (error) {
|
|
97
|
+
console.error('Error from Branch:', error);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (params['+clicked_branch_link']) {
|
|
102
|
+
const referringLink = params['~referring_link'];
|
|
103
|
+
if (referringLink) {
|
|
104
|
+
try {
|
|
105
|
+
const insertAffiliateIdentifier = await setInsertAffiliateIdentifier(referringLink);
|
|
106
|
+
|
|
107
|
+
if (insertAffiliateIdentifier) {
|
|
108
|
+
await adapty.updateProfile({
|
|
109
|
+
codableCustomAttributes: {
|
|
110
|
+
insert_affiliate: insertAffiliateIdentifier,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
} catch (err) {
|
|
115
|
+
console.error('Error setting affiliate identifier:', err);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
return () => {
|
|
122
|
+
branchSubscription();
|
|
123
|
+
};
|
|
124
|
+
}, [setInsertAffiliateIdentifier]);
|
|
125
|
+
|
|
126
|
+
return <App />;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const RootComponent = () => {
|
|
130
|
+
return (
|
|
131
|
+
<DeepLinkIapProvider>
|
|
132
|
+
<DeepLinkHandler />
|
|
133
|
+
</DeepLinkIapProvider>
|
|
134
|
+
);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
AppRegistry.registerComponent(appName, () => RootComponent);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Example with Apphud
|
|
141
|
+
|
|
142
|
+
```javascript
|
|
143
|
+
import React, { useEffect } from 'react';
|
|
144
|
+
import { AppRegistry } from 'react-native';
|
|
145
|
+
import branch from 'react-native-branch';
|
|
146
|
+
import Apphud from 'react-native-apphud';
|
|
147
|
+
import { useDeepLinkIapProvider, DeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
|
|
148
|
+
import App from './App';
|
|
149
|
+
import { name as appName } from './app.json';
|
|
150
|
+
|
|
151
|
+
const DeepLinkHandler = () => {
|
|
152
|
+
const { setInsertAffiliateIdentifier } = useDeepLinkIapProvider();
|
|
153
|
+
|
|
154
|
+
useEffect(() => {
|
|
155
|
+
const branchSubscription = branch.subscribe(async ({ error, params }) => {
|
|
156
|
+
if (error) {
|
|
157
|
+
console.error('Error from Branch:', error);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (params['+clicked_branch_link']) {
|
|
162
|
+
const referringLink = params['~referring_link'];
|
|
163
|
+
if (referringLink) {
|
|
164
|
+
try {
|
|
165
|
+
const insertAffiliateIdentifier = await setInsertAffiliateIdentifier(referringLink);
|
|
166
|
+
|
|
167
|
+
if (insertAffiliateIdentifier) {
|
|
168
|
+
await Apphud.setUserProperty("insert_affiliate", insertAffiliateIdentifier, false);
|
|
169
|
+
}
|
|
170
|
+
} catch (err) {
|
|
171
|
+
console.error('Error setting affiliate identifier:', err);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
return () => {
|
|
178
|
+
branchSubscription();
|
|
179
|
+
};
|
|
180
|
+
}, [setInsertAffiliateIdentifier]);
|
|
181
|
+
|
|
182
|
+
return <App />;
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const RootComponent = () => {
|
|
186
|
+
return (
|
|
187
|
+
<DeepLinkIapProvider>
|
|
188
|
+
<DeepLinkHandler />
|
|
189
|
+
</DeepLinkIapProvider>
|
|
190
|
+
);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
AppRegistry.registerComponent(appName, () => RootComponent);
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Example with Iaptic
|
|
197
|
+
|
|
198
|
+
```javascript
|
|
199
|
+
import React, { useEffect } from 'react';
|
|
200
|
+
import { AppRegistry } from 'react-native';
|
|
201
|
+
import branch from 'react-native-branch';
|
|
202
|
+
import { useDeepLinkIapProvider, DeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
|
|
203
|
+
import App from './App';
|
|
204
|
+
import { name as appName } from './app.json';
|
|
205
|
+
|
|
206
|
+
const DeepLinkHandler = () => {
|
|
207
|
+
const { setInsertAffiliateIdentifier } = useDeepLinkIapProvider();
|
|
208
|
+
|
|
209
|
+
useEffect(() => {
|
|
210
|
+
const branchSubscription = branch.subscribe(async ({ error, params }) => {
|
|
211
|
+
if (error) {
|
|
212
|
+
console.error('Error from Branch:', error);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (params['+clicked_branch_link']) {
|
|
217
|
+
const referringLink = params['~referring_link'];
|
|
218
|
+
if (referringLink) {
|
|
219
|
+
try {
|
|
220
|
+
await setInsertAffiliateIdentifier(referringLink);
|
|
221
|
+
console.log('Affiliate identifier set successfully.');
|
|
222
|
+
} catch (err) {
|
|
223
|
+
console.error('Error setting affiliate identifier:', err);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
return () => branchSubscription();
|
|
230
|
+
}, [setInsertAffiliateIdentifier]);
|
|
231
|
+
|
|
232
|
+
return <App />;
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
const RootComponent = () => {
|
|
236
|
+
return (
|
|
237
|
+
<DeepLinkIapProvider>
|
|
238
|
+
<DeepLinkHandler />
|
|
239
|
+
</DeepLinkIapProvider>
|
|
240
|
+
);
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
AppRegistry.registerComponent(appName, () => RootComponent);
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Example with App Store / Google Play Direct Integration
|
|
247
|
+
|
|
248
|
+
```javascript
|
|
249
|
+
import React, { useEffect } from 'react';
|
|
250
|
+
import { AppRegistry } from 'react-native';
|
|
251
|
+
import branch from 'react-native-branch';
|
|
252
|
+
import { useDeepLinkIapProvider, DeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
|
|
253
|
+
import App from './App';
|
|
254
|
+
import { name as appName } from './app.json';
|
|
255
|
+
|
|
256
|
+
const DeepLinkHandler = () => {
|
|
257
|
+
const { setInsertAffiliateIdentifier } = useDeepLinkIapProvider();
|
|
258
|
+
|
|
259
|
+
useEffect(() => {
|
|
260
|
+
const branchSubscription = branch.subscribe(async ({ error, params }) => {
|
|
261
|
+
if (error) {
|
|
262
|
+
console.error('Error from Branch:', error);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (params['+clicked_branch_link']) {
|
|
267
|
+
const referringLink = params['~referring_link'];
|
|
268
|
+
if (referringLink) {
|
|
269
|
+
try {
|
|
270
|
+
await setInsertAffiliateIdentifier(referringLink);
|
|
271
|
+
// Affiliate identifier is stored automatically for direct store integration
|
|
272
|
+
} catch (err) {
|
|
273
|
+
console.error('Error setting affiliate identifier:', err);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
return () => branchSubscription();
|
|
280
|
+
}, [setInsertAffiliateIdentifier]);
|
|
281
|
+
|
|
282
|
+
return <App />;
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
const RootComponent = () => {
|
|
286
|
+
return (
|
|
287
|
+
<DeepLinkIapProvider>
|
|
288
|
+
<DeepLinkHandler />
|
|
289
|
+
</DeepLinkIapProvider>
|
|
290
|
+
);
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
AppRegistry.registerComponent(appName, () => RootComponent);
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Testing
|
|
297
|
+
|
|
298
|
+
Test your Branch deep link integration:
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
# Test with your Branch link (iOS Simulator)
|
|
302
|
+
xcrun simctl openurl booted "https://your-app.app.link/abc123"
|
|
303
|
+
|
|
304
|
+
# Test with your Branch link (Android Emulator)
|
|
305
|
+
adb shell am start -W -a android.intent.action.VIEW -d "https://your-app.app.link/abc123"
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## Troubleshooting
|
|
309
|
+
|
|
310
|
+
**Problem:** `~referring_link` is null
|
|
311
|
+
- **Solution:** Ensure Branch SDK is properly initialized before Insert Affiliate SDK
|
|
312
|
+
- Verify Branch link is properly configured with your app's URI scheme
|
|
313
|
+
|
|
314
|
+
**Problem:** Deep link opens browser instead of app
|
|
315
|
+
- **Solution:** Check Branch dashboard for associated domains configuration
|
|
316
|
+
- Verify your app's entitlements include the Branch link domain (iOS)
|
|
317
|
+
- Verify AndroidManifest.xml has correct intent filters (Android)
|
|
318
|
+
|
|
319
|
+
**Problem:** Deferred deep linking not working
|
|
320
|
+
- **Solution:** Make sure you're using `branch.subscribe()` correctly
|
|
321
|
+
- Test with a fresh app install (uninstall/reinstall)
|
|
322
|
+
|
|
323
|
+
## Next Steps
|
|
324
|
+
|
|
325
|
+
After completing Branch integration:
|
|
326
|
+
1. Test deep link attribution with a test affiliate link
|
|
327
|
+
2. Verify affiliate identifier is stored correctly
|
|
328
|
+
3. Make a test purchase to confirm tracking works end-to-end
|
|
329
|
+
|
|
330
|
+
[Back to Main README](../readme.md)
|