Skip to content

Commit 852a0de

Browse files
committed
docs: consolidate 6.x to 7.0.0 migration guide, deslop integration docs
MIGRATION.md's three overlapping lists (callback-removal prose, symbol table, alignment table) are replaced by one alphabetical Full API change reference table covering every affected symbol, plus a TOC and a tightened LLM-assistant prompt. Docs/RN_API.md gets an upgrading-from-6.x callout linking to MIGRATION.md, and its links into MIGRATION.md are repointed from anchors that never existed (table rows have no anchor) to real headings. The remaining Docs/*.md files get formatting cleanup and removal of stale 6.x-era examples, continuing the RPC-to-Plugin-API alignment doc pass from the previous commit.
1 parent 6544eab commit 852a0de

16 files changed

Lines changed: 522 additions & 1021 deletions

‎Docs/RN_API.md‎

Lines changed: 153 additions & 250 deletions
Large diffs are not rendered by default.

‎Docs/RN_CMP.md‎

Lines changed: 18 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Through a dedicated SDK API: Developers can pass Google's required consent data
1919
A CMP compatible with TCF v2.2/2.3 collects DMA consent data and stores it in NSUserDefaults (iOS) and SharedPreferences (Android). To enable the SDK to access this data and include it with every event, follow these steps:
2020

2121
1. Call `appsFlyer.enableTCFDataCollection(true)`
22-
2. `init(devKey, appId)` and register listeners as usual (see [Initialization Flow](RN_API.md#initialization-flow)) — 7.0.0 always requires an explicit `start()` call, so there is no separate "manual start" mode to opt into.
22+
2. `init(devKey, appId)` and register listeners as usual (see [Initialization Flow](RN_API.md#initialization-flow)).
2323
3. Use the CMP to decide if you need the consent dialog in the current session to acquire the consent data. If you need the consent dialog move to step 4; otherwise move to step 5
2424
4. Get confirmation from the CMP that the user has made their consent decision and the data is available in NSUserDefaults/SharedPreferences
2525
5. Call `appsFlyer.start()` from inside `registerSessionReadyListener`'s callback, after the CMP decision is resolved
@@ -51,17 +51,18 @@ useEffect(() => {
5151

5252
If your app does not use a TCF v2.2/2.3-compatible CMP, you must manually provide the consent data using the SDK API.
5353

54-
How to Set Consent Data: </br>
55-
1. Determine GDPR Applicability:
56-
* If GDPR applies, check whether consent data is already stored.
57-
* If not stored, show a consent dialog to obtain user consent.
58-
2. Create an AppsFlyerConsent object with the relevant parameters.
59-
3. Pass the consent data to the SDK using appsFlyer.setConsentData(consentData) inside `registerSessionReadyListener`'s callback, before calling `start()`.
60-
4. Initialize the SDK with `appsFlyer.init(devKey, appId)` (see [Initialization Flow](RN_API.md#initialization-flow)).
54+
How to Set Consent Data:
55+
56+
1. Determine GDPR Applicability:
57+
- If GDPR applies, check whether consent data is already stored.
58+
- If not stored, show a consent dialog to obtain user consent.
59+
2. Create an AppsFlyerConsent object with the relevant parameters.
60+
3. Pass the consent data to the SDK using appsFlyer.setConsentData(consentData) inside `registerSessionReadyListener`'s callback, before calling `start()`.
61+
4. Initialize the SDK with `appsFlyer.init(devKey, appId)` (see [Initialization Flow](RN_API.md#initialization-flow)).
6162

6263
#### Setting Consent Data for Users
6364

64-
<b>When GDPR Applies</b>
65+
##### When GDPR Applies
6566

6667
If GDPR applies to the user, create an AppsFlyerConsent object with the user’s preferences.
6768
```javascript
@@ -86,29 +87,16 @@ useEffect(() => {
8687
}, []);
8788
```
8889

89-
<b>When GDPR Does Not Apply</b>
90-
91-
If GDPR does not apply to the user, simply mark it as such in the AppsFlyerConsent object.
92-
```javascript
93-
import appsFlyer, { AppsFlyerConsent } from 'react-native-appsflyer';
94-
95-
useEffect(() => {
96-
appsFlyer.init('UxXxXxXxXd', '41*****44').then(
97-
res => console.log(res),
98-
err => console.log(err)
99-
);
100-
appsFlyer.enableDebug(true);
90+
##### When GDPR Does Not Apply
10191

102-
appsFlyer.registerSessionReadyListener(() => {
103-
// GDPR does not apply to the user
104-
const consentData = new AppsFlyerConsent(false);
92+
If GDPR does not apply to the user, simply mark it as such in the AppsFlyerConsent object. Use the same initialization flow as above, but with a different consent constructor call:
10593

106-
// Send consent data to the SDK
107-
appsFlyer.setConsentData(consentData);
94+
```javascript
95+
// GDPR does not apply to the user
96+
const consentData = new AppsFlyerConsent(false);
10897

109-
appsFlyer.start();
110-
});
111-
}, []);
98+
appsFlyer.setConsentData(consentData);
99+
appsFlyer.start();
112100
```
113101

114102
### Consent Object API
@@ -134,17 +122,8 @@ const consent2 = new AppsFlyerConsent(true, false, false, false);
134122
// Non-GDPR user
135123
const consent3 = new AppsFlyerConsent(false);
136124

137-
// AppsFlyerConsent object support the following cases if they are needed.
125+
// Partial consent (only GDPR flag, other parameters optional)
138126
const consent4 = new AppsFlyerConsent(true);
139-
const consent5 = new AppsFlyerConsent(true, true);
140-
const consent6 = new AppsFlyerConsent(null, true, true, true);
141-
const consent7 = new AppsFlyerConsent(true, null, true, true);
142-
const consent8 = new AppsFlyerConsent(true, true, null, true);
143-
const consent9 = new AppsFlyerConsent(true, true, true, null);
144-
const consent10 = new AppsFlyerConsent(true, true, false, true);
145-
const consent11 = new AppsFlyerConsent(false, true, false, false);
146-
const consent12 = new AppsFlyerConsent(null, null, null, null);
147-
const consent13 = new AppsFlyerConsent();
148127
```
149128

150129
### Removed API

‎Docs/RN_DeepLinkIntegrate.md‎

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ public class MainActivity extends ReactActivity {
3636
}
3737
```
3838

39+
**Cold-start deep links**: The native SDK inspects the launch Intent only after `init()` completes. For cold-start deep links (app not running when link is clicked), re-deliver them via `Linking.getInitialURL()` and `appsFlyer.performDeepLinking()` inside `init().then()`:
40+
41+
```javascript
42+
appsFlyer.init(devKey, appId)
43+
.then(async () => {
44+
const url = await Linking.getInitialURL();
45+
if (url) {
46+
await appsFlyer.performDeepLinking(url, true);
47+
}
48+
});
49+
```
50+
3951
### App Links
4052
First, you need to generate SHA256 fingerprint, then add the following intent-filter to the relevant activity in your app’s manifest:
4153
```xml
@@ -49,9 +61,11 @@ First, you need to generate SHA256 fingerprint, then add the following intent-fi
4961
android:scheme="https" />
5062
</intent-filter>
5163
```
52-
For more on App Links check out the guide [here](https://dev.appsflyer.com/hc/docs/dl_android_init_setup#procedures-for-android-app-links).
64+
See the [guide](https://dev.appsflyer.com/hc/docs/dl_android_init_setup#procedures-for-android-app-links) for App Links setup.
5365

5466
### URI Scheme
67+
A URI scheme is a URL that leads users directly to the mobile app. When an app user enters a URI scheme in a browser address bar or clicks on a link based on a URI scheme, the app launches and the user is deep-linked.
68+
5569
In your app’s manifest add the following intent-filter to your relevant activity:
5670
```xml
5771
<intent-filter>
@@ -64,10 +78,10 @@ In your app’s manifest add the following intent-filter to your relevant activi
6478
android:scheme="afshopapp" />
6579
</intent-filter>
6680
```
67-
For more on URI Scheme check out the guide [here](https://dev.appsflyer.com/hc/docs/dl_android_init_setup#procedures-for-uri-scheme).
81+
For URI Scheme setup, see the [guide](https://dev.appsflyer.com/hc/docs/dl_android_init_setup#procedures-for-uri-scheme).
6882

6983
## iOS Deeplink Setup
70-
In order to record retargeting and use the `registerDeepLinkListener`/UDL callback in iOS (`onAppOpenAttribution` was removed in 7.0.0 and merged into `registerDeepLinkListener` — see MIGRATION.md), the app needs to forward opened URLs / Universal Links / cold-start launch options to the native SDK. This is done entirely in your app's native **AppDelegate** — there is no JavaScript API for this (`handleOpenURL`/`handleOpenUrl`/`continueUserActivity`/`handleLaunchOptions` are not exposed by this plugin's JS surface):
84+
In order to record retargeting and use the `registerDeepLinkListener`/UDL callback in iOS (`onAppOpenAttribution` was removed in 7.0.0 and merged into `onDeepLink`, which was later renamed to `registerDeepLinkListener` — see MIGRATION.md), the app needs to forward opened URLs / Universal Links / cold-start launch options to the native SDK. This is done entirely in your app's native **AppDelegate** — there is no JavaScript API for this (`handleOpenURL`/`handleOpenUrl`/`continueUserActivity`/`handleLaunchOptions` are not exposed by this plugin's JS surface):
7185

7286
```swift
7387
import AppsFlyerLib
@@ -94,7 +108,7 @@ func application(_ application: UIApplication,
94108

95109
`AppsFlyerLib` is already available as a transitive dependency of this plugin (via the vendored `AppsFlyerRPC` pod) — no extra `pod` entry is needed to `import AppsFlyerLib` in your own AppDelegate.
96110

97-
**Expo apps**: the `openURL`/`continueUserActivity` forwarding above is auto-injected into your generated AppDelegate by this plugin's config plugin at `expo prebuild` time (see [Expo Deep Link Integration](/Docs/RN_ExpoDeepLinkIntegration.md)) — you don't need to add it by hand. `handleLaunchOptions` isn't auto-injected yet; add it manually if you need cold-start launch options forwarded.
111+
**Expo apps**: the `openURL`/`continueUserActivity` and `handleLaunchOptions` forwarding above is auto-injected into your generated AppDelegate by this plugin's config plugin at `expo prebuild` time (see [Expo Deep Link Integration](/Docs/RN_ExpoDeepLinkIntegration.md)) — you don't need to add it by hand for either ObjC or Swift AppDelegate templates.
98112

99113
### Universal Links
100114
Universal Links link between an iOS mobile app and an associate website/domain, such as AppsFlyer’s OneLink domain (xxx.onelink.me). To do so, it is required to:
@@ -115,12 +129,9 @@ Universal Links link between an iOS mobile app and an associate website/domain,
115129
</plist>
116130
```
117131

118-
For more on Universal Links check out the guide [here](https://dev.appsflyer.com/hc/docs/dl_ios_init_setup#procedures-for-ios-universal-links).
132+
For more on Universal Links, check the [guide](https://dev.appsflyer.com/hc/docs/dl_ios_init_setup#procedures-for-ios-universal-links).
119133

120134
### URI Scheme
121-
A URI scheme is a URL that leads users directly to the mobile app.
122-
When an app user enters a URI scheme in a browser address bar box, or clicks on a link based on a URI scheme, the app launches and the user is deep-linked.
123-
124135
To configure it you will have to:
125136

126137
1. Add a unique url identifier in the URL types entry in the app's `info.plist`
@@ -149,4 +160,4 @@ example of a URL scheme configuration in the `info.plist`:
149160
</plist>
150161
```
151162

152-
For more on URI Scheme check out the guide [here](https://dev.appsflyer.com/hc/docs/dl_ios_init_setup#procedures-for-uri-scheme).
163+
For URI Scheme configuration, see the [guide](https://dev.appsflyer.com/hc/docs/dl_ios_init_setup#procedures-for-uri-scheme).

‎Docs/RN_EspIntegration.md‎

Lines changed: 24 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@ hidden: false
1010

1111
ESP (Email Service Provider) support allows AppsFlyer to handle deep links that are wrapped by email service providers. When users click links in emails, ESP services often wrap the original URL with their own tracking domains. This can break deep linking functionality. ESP support resolves these wrapped URLs to extract the original deep link.
1212

13-
### How ESP Works:
14-
1. **Email Campaign**: Your email contains a deep link to your app
15-
2. **ESP Wrapping**: Email provider wraps your link with their tracking domain
16-
3. **User Clicks**: User clicks the wrapped link from their email
17-
4. **ESP Resolution**: AppsFlyer resolves the wrapped URL to get the original link
18-
5. **Decision**: If original link is a OneLink → continue deep linking; if web URL → open in browser
1913

2014
## 🚀 Prerequisites
2115

@@ -106,7 +100,7 @@ public class AppDelegate: ExpoAppDelegate {
106100
}
107101
```
108102

109-
See [Deep linking integration](RN_DeepLinkIntegrate.md#ios-deeplink-setup) for the full native pattern (this plugin's Expo config plugin auto-injects the `openURL`/`continueUserActivity` calls above at `expo prebuild` time — `handleLaunchOptions` is not auto-injected yet).
103+
See [Deep linking integration](RN_DeepLinkIntegrate.md#ios-deeplink-setup) for the full native pattern (this plugin's Expo config plugin auto-injects the `openURL`/`continueUserActivity` and `handleLaunchOptions` calls above at `expo prebuild` time).
110104

111105
---
112106

@@ -243,17 +237,15 @@ import appsFlyer from 'react-native-appsflyer';
243237
* This MUST be called before AppsFlyer SDK initialization
244238
*/
245239
const configureESPDomains = () => {
246-
console.log('🔗 Configuring ESP domains:', ESP_DOMAINS);
240+
console.log('Configuring ESP domains:', ESP_DOMAINS);
247241

248-
appsFlyer.setResolveDeepLinkURLs(
249-
ESP_DOMAINS,
250-
(result) => {
251-
console.log('✅ ESP domains configured successfully:', result);
252-
},
253-
(error) => {
254-
console.error('❌ ESP domain configuration failed:', error);
255-
}
256-
);
242+
appsFlyer.setResolveDeepLinkURLs(ESP_DOMAINS)
243+
.then((result) => {
244+
console.log('ESP domains configured successfully:', result);
245+
})
246+
.catch((error) => {
247+
console.error('ESP domain configuration failed:', error);
248+
});
257249
};
258250
```
259251

@@ -266,11 +258,11 @@ const configureESPDomains = () => {
266258
* Main ESP deep link handler
267259
*/
268260
const handleEspDeepLink = useCallback((deepLinkData: any) => {
269-
console.log('🔗 Deep Link Received:', deepLinkData);
261+
console.log('Deep Link Received:', deepLinkData);
270262

271263
// Simply stringify and display the entire deep link data
272264
const formattedData = JSON.stringify(deepLinkData, null, 2);
273-
console.log('📱 Deep Link Data:', formattedData);
265+
console.log('Deep Link Data:', formattedData);
274266

275267
let actualDeepLinkData = deepLinkData;
276268

@@ -320,8 +312,7 @@ const handleEspDeepLink = useCallback((deepLinkData: any) => {
320312
} else {
321313
console.log('[AFSDK] The ESP link is NOT a OneLink link. It will be opened in a browser');
322314
console.log('[AFSDK] ESP marks to divert the link to the browser');
323-
console.log('URL to open:', espUrl.toString());
324-
console.log('📱 Would open in browser:', espUrl.toString());
315+
console.log('URL to open:', espUrl.toString());
325316
}
326317
} else {
327318
console.log('[AFSDK] No host found in the ESP URL');
@@ -345,10 +336,10 @@ const handleEspDeepLink = useCallback((deepLinkData: any) => {
345336
}
346337
} else {
347338
console.log('[AFSDK] The original_link is not found');
348-
console.log('📋 Regular Deep Link Data:', actualDeepLinkData.data);
339+
console.log('Regular Deep Link Data:', actualDeepLinkData.data);
349340
}
350341
}
351-
});
342+
}, []);
352343
```
353344
354345
### Step 4: SDK Initialization with ESP
@@ -360,7 +351,7 @@ import { useEffect } from 'react';
360351
import { Platform } from 'react-native';
361352

362353
const initializeAppsFlyer = () => {
363-
console.log('🚀 Initializing AppsFlyer with ESP support...');
354+
console.log('Initializing AppsFlyer with ESP support...');
364355

365356
// 1. Configure ESP domains FIRST
366357
configureESPDomains();
@@ -371,10 +362,10 @@ const initializeAppsFlyer = () => {
371362
// 3. Set up conversion data listener
372363
appsFlyer.registerConversionListener(
373364
(res) => {
374-
console.log('📊 Conversion Data:', res);
365+
console.log('Conversion Data:', res);
375366
},
376367
(error) => {
377-
console.error('❌ Conversion Data Error:', error);
368+
console.error('Conversion Data Error:', error);
378369
}
379370
);
380371

@@ -387,10 +378,10 @@ const initializeAppsFlyer = () => {
387378

388379
appsFlyer.init(devKey, "YOUR_IOS_APP_ID").then(
389380
() => {
390-
console.log("✅ AppsFlyer SDK initialized successfully!");
381+
console.log("AppsFlyer SDK initialized successfully!");
391382
},
392383
(err) => {
393-
console.error("❌ AppsFlyer SDK initialization error:", err);
384+
console.error("AppsFlyer SDK initialization error:", err);
394385
}
395386
);
396387
};
@@ -407,75 +398,27 @@ useEffect(() => {
407398
408399
### Common Android Issues
409400
410-
**1. Deep links open Google Play instead of app:**
411-
- Remove `android:autoVerify="true"` from intent filters
412-
- Test with ADB for direct app opening
413-
- Ensure app is installed and intent filters are correct
401+
For general Android configuration issues (manifest merging, package attribute deprecation, autoVerify behavior, backup rules), refer to the [known-issues knowledge base](../Docs/RN_API.md) and [AppsFlyer Android SDK documentation](https://dev.appsflyer.com/hc/docs/install-android-sdk).
414402
415-
**2. Email deep links redirect to Play Store (Domain Disabled):**
403+
**ESP-Specific: Domain Verification Issues**
416404
417-
This is a common issue where clicking deep links from emails opens the Play Store instead of your app. This happens when the domain is disabled in Android's app link settings.
405+
When deep links from emails open the Play Store instead of your app, the domain may be disabled in Android's app link settings.
418406
419407
**Diagnosis:**
420408
```bash
421-
# Check if your app's domain is disabled
422409
adb shell pm get-app-links com.yourcompany.yourapp
423410
```
424411
425-
Look for your domain in the "Selection state" → "Disabled" section.
426-
427412
**Solution:**
428413
```bash
429-
# Enable domain for your app (replace with your actual package name and domain)
414+
# Enable domain for your app
430415
adb shell pm set-app-links-user-selection --package com.yourcompany.yourapp --user 0 true your-onelink-domain.onelink.me
431416

432-
# Verify the fix
433-
adb shell pm get-app-links com.yourcompany.yourapp
434-
```
435-
436-
**Testing:**
437-
```bash
438-
# Test deep link after fix
417+
# Test the fix
439418
adb shell am force-stop com.yourcompany.yourapp
440419
adb shell am start -W -a android.intent.action.VIEW -d "https://your-onelink-domain.onelink.me/test"
441420
```
442421
443-
**Production Note:** This is a testing solution. For production apps, consider:
444-
- Domain verification (requires access to domain)
445-
- User education about setting app as default handler
446-
- Fallback handling for when app isn't the default handler
447-
448-
**3. Manifest merger conflicts:**
449-
```xml
450-
<!-- Add tools namespace and replace directive -->
451-
<manifest xmlns:tools="http://schemas.android.com/tools">
452-
<application android:allowBackup="false" tools:replace="android:allowBackup">
453-
```
454-
See [AppsFlyer Android SDK documentation](https://dev.appsflyer.com/hc/docs/install-android-sdk#backup-rules) for more details.
455-
456-
**4. Package attribute deprecated:**
457-
- Remove `package="com.yourapp"` from AndroidManifest.xml
458-
- Use `namespace` in build.gradle instead
459-
460-
**5. Build Cache Issues:**
461-
462-
If experiencing persistent build failures, perform a complete clean build:
463-
```bash
464-
# Clean everything
465-
rm -rf node_modules
466-
rm -rf ios/Pods
467-
rm -rf android/.gradle
468-
rm -rf android/app/build
469-
rm -rf android/build
470-
471-
# Reinstall dependencies
472-
npm install
473-
cd ios && pod install && cd ..
474-
475-
# Clean build
476-
npx expo run:android / ios --clear
477-
```
478-
479422
### Common iOS Issues
480423
481424
**1. Universal Links not working:**

0 commit comments

Comments
 (0)