appsFlyer.onDeepLink() Not Triggering in Kill State on iOS with Latest Version
Summary: After upgrading to React Native 0.79.0 and [email protected], the appsFlyer.onDeepLink() listener stops consistently firing in iOS kill state. It works sometimes, but most of the time it doesn't. The same implementation worked reliably in [email protected] and [email protected].
✅ Previously Working Versions React Native: 0.71.11 AppsFlyer SDK: react-native-appsflyer@^6.12.2 In the working setup, the OneLink consistently triggered appsFlyer.onDeepLink() in: Foreground ✅ Background ✅ Kill State ✅
📄 Universal Link (AASA) Setup Hosted at: https://test.onelink.me/.well-known/apple-app-site-association (sample url) MIME Type: application/pkcs7-mime (.p7m) AASA file verified and working correctly
Objective-C Code That Worked AppDelegate.mm
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if ([RCTLinkingManager application:app openURL:url options:options]) return YES;
[[AppsFlyerAttribution shared] handleOpenUrl:url options:options];
return YES;
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler {
[RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
[[AppsFlyerAttribution shared] continueUserActivity:userActivity restorationHandler:restorationHandler];
return YES;
}
App.js
useEffect(() => {
appsFlyer.onDeepLink(res => {
console.log('onDeepLink:', res);
});
appsFlyer.initSdk({
devKey: 'XXX',
appId: '123456789',
isDebug: true,
onInstallConversionDataListener: true,
onDeepLinkListener: true,
timeToWaitForATTUserAuthorization: 10,
},
result => console.log('SDK init success', result),
error => console.log('SDK init error', error));
}, []);
❌ Current Setup (RN 0.79.0 + SDK 6.16.2)
🔧Affected Versions React Native: 0.79.0 AppsFlyer SDK: react-native-appsflyer@^6.16.2 iOS Version: Tested on iOS 17.x
🧪 Current Behavior (v6.16.2 + RN 0.79.0) Foreground: appsFlyer.onDeepLink() ✅ Background: appsFlyer.onDeepLink() ✅ Kill State: appsFlyer.onDeepLink() ❌ (Inconsistent or not firing at all)
📄 Universal Link (AASA) Setup ✅ No changes were made to the AASA configuration between the working and non-working versions. ✅ Same setup used in working version ([email protected], [email protected]) Hosted at: https://test.onelink.me/.well-known/apple-app-site-association (sample url) MIME Type: application/pkcs7-mime (.p7m) AASA file verified and working correctly
Swift AppDelegate Code
AppDelegate.swift
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
AppsFlyerLib.shared().appsFlyerDevKey = "XXX"
AppsFlyerLib.shared().appleAppID = "123456789"
AppsFlyerLib.shared().delegate = self
AppsFlyerLib.shared().isDebug = true
AppsFlyerLib.shared().start()
return true
}
// iOS 9+ - Open URI Scheme
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
AppsFlyerLib.shared().handleOpen(url, options: options) // no return value
let handledRCT = RCTLinkingManager.application(app, open: url, options: options)
return handledRCT // return only the actual Bool
}
// iOS 8 and below - Open URI Scheme
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
AppsFlyerLib.shared().handleOpen(url, sourceApplication: sourceApplication, withAnnotation: annotation)
return true
}
// Universal Links
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
let handledRCT = RCTLinkingManager.application(
application,
continue: userActivity,
restorationHandler: restorationHandler
)
AppsFlyerLib.shared().continue(userActivity, restorationHandler: nil)
return handledRCT
}
React Native
App.js
useEffect(() => {
appsFlyer.onDeepLink(res => {
console.log('onDeepLink:', res);
});
appsFlyer.initSdk({
devKey: 'XXX',
appId: '123456789',
isDebug: true,
onInstallConversionDataListener: true,
onDeepLinkListener: true,
timeToWaitForATTUserAuthorization: 10,
},
result => console.log('SDK init success', result),
error => console.log('SDK init error', error));
}, []);
Hi Team,
Is there any update on this issue?
We’ve observed that when an AppsFlyer Universal Link is clicked while the app is in the background, the appsFlyer.onDeepLink listener is triggered as expected.
However, when the app is launched from a cold (quit) state via the same Universal Link, the appsFlyer.onDeepLink listener does not get called.
i also face same issue class AppDelegate: RCTAppDelegate { override func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool { AppsFlyerLib.shared().handleOpen(url, sourceApplication: sourceApplication, withAnnotation: annotation) return true }
override func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { AppsFlyerLib.shared().handleOpen(url, options: options) RCTLinkingManager.application(application, open: url, options: options) return true }
override func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { AppsFlyerLib.shared().continue(userActivity, restorationHandler:nil) RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler) return true }
......
Hi, I have the same problem with cold start on ios, is there any solution?
any success on this issue?
I faced same issues?? Any solution???
any solution for this issue? please help
same issue with expo 53
I believe the issue is a limitation from AppsFlyer. Please see the link below: https://www.appsflyer.com/use-cases/customer-experience-deep-linking/universal-linking-challenges-ios-10-3/
I encountered this issue when copying and pasting the OneLink into a browser—it doesn't work. Try this instead: generate a QR code from the OneLink and scan it. It will open and trigger onDeeplinking. This issue only occurs on iOS.
And if you wanna fix this issue, please check fallback url ...
I found an issue: on iOS, deeplinks/appsFlyer.onDeeplink() do not work when app is in Killed State, in the two cases below:
- Universal Links don’t load in when pasted into browsers
- Facebook does not possible to deep link from posts to the Facebook feed
Solution: Create function to handle fallback uri from one link (instead of function callback inside appsFlyer.onDeeplink())
Step 1: Config the fallback link in AppsFlyer Dashboard
Step 2: Use Linking for get URL fallback Code Example below
import { Linking } from 'react-native';
const getFallbackData = async (): Promise<UnifiedDeepLinkData | undefined> => {
const url = await Linking.getInitialURL();
if (!url || !url.startsWith('abc')) return;
const url = new URL(urlString);
const params: Record<string, string> = {};
for (const [key, value] of url.searchParams.entries()) {
params[key] = value;
}
return {
url,
params
};
};
Step 3: Create new function handle fallback like callback in appsFlyer.onDeeplink(callback)
I found an issue: on iOS, deeplinks/appsFlyer.onDeeplink() do not work when app is in Killed State, in the two cases below:
- Universal Links don’t load in when pasted into browsers
- Facebook does not possible to deep link from posts to the Facebook feed
Solution: Create function to handle fallback uri from one link (instead of function callback inside appsFlyer.onDeeplink())
Step 1: Config the fallback link in AppsFlyer Dashboard
Step 2: Use Linking for get URL fallback Code Example below
import { Linking } from 'react-native'; const getFallbackData = async (): Promise<UnifiedDeepLinkData | undefined> => { const url = await Linking.getInitialURL(); if (!url || !url.startsWith('abc')) return; const query = url.split('?')[1]; if (!query) return; const params = Object.fromEntries( query.split('&').map((pair) => pair.split('=').map(decodeURIComponent)), ); return { deepLinkStatus: 'FOUND', status: 'success', type: 'onDeepLinking', data: params, isDeferred: false, }; };Step 3: Create new function handle fallback like callback in appsFlyer.onDeeplink(callback)
kaka this work for me. tks a lot 👍
@Tuan2109 what if I am using short url and doesn't have parameters attached to it and can only be fetched using deeplink function then how we can achieve it ? as it seems that parameters are not fetched from this way. for (const [key, value] of url.searchParams.entries()) { params[key] = value; } and using alternative way like this :
const params = Object.fromEntries( query.split('&').map((pair) => pair.split('=').map(decodeURIComponent)), ); will require parameters to be attached to the uri means long uri required.
Look at the difference between Objective-C and Swift code.
For Objective-C, you are using (as written in our documentation) AppsFlyerAttribution, while AppsFlyerLib is used in your Swift example.
The issue with AppsFlyerLib is that the deep link resolution is done before the bridge between JS and Native layers is established.
To handle such cases, you should use AppsFlyerAttribution, which waits for the bridge to be ready before performing the deep link resolution.
To work with AppsFlyerAttribution in Swift, you'll have to create a Bridging Header file.
For any future assistant, please open a support ticket.
👋 Hi @Akilramki and Thank you for reaching out to us. You can contact AppsFlyer support through the Customer Assistant Chatbot for assistance with troubleshooting issues or product guidance. To do so, please follow this article.
Thanks a lot for this comment @pazlavi — it helped me identify and solve the exact issue I was facing with deep links not firing on cold start in iOS when using React Native.
For anyone integrating react-native-appsflyer in a Swift-based project, here's what finally worked for me:
✅ Problem: Using AppsFlyerLib.shared() in AppDelegate.swift was causing deep links (especially OneLink) to fail on cold start — exactly as mentioned here: the resolution was happening before the JS bridge was ready.
✅ Fix: Replaced AppsFlyerLib with AppsFlyerAttribution in Swift, like so:
func application( _ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:] ) -> Bool { AppsFlyerAttribution.shared().handleOpen(url, options: options)
// React Native Linking
return RCTLinkingManager.application(application, open: url, options: options)
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { AppsFlyerAttribution.shared().continue(userActivity, restorationHandler: nil) return true }
Did not try to import AppsFlyerAttribution in Swift directly (which fails)
➡️ Instead, added this to Bridging Header file in your project:
#import <RNAppsFlyer.h>
This exposes the internal Objective-C implementation from react-native-appsflyer, including AppsFlyerAttribution.
✅ Result: After making this change, onDeepLink() is reliably triggered even on cold start.
Looks like this has been fixed, both in the docs as well as the Expo plugin. Can we close this?
Thanks a lot for this comment @pazlavi — it helped me identify and solve the exact issue I was facing with deep links not firing on cold start in iOS when using React Native.
For anyone integrating react-native-appsflyer in a Swift-based project, here's what finally worked for me:
✅ Problem: Using AppsFlyerLib.shared() in AppDelegate.swift was causing deep links (especially OneLink) to fail on cold start — exactly as mentioned here: the resolution was happening before the JS bridge was ready.
✅ Fix: Replaced AppsFlyerLib with AppsFlyerAttribution in Swift, like so:
func application( _ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:] ) -> Bool { AppsFlyerAttribution.shared().handleOpen(url, options: options)
// React Native Linking return RCTLinkingManager.application(application, open: url, options: options)}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { AppsFlyerAttribution.shared().continue(userActivity, restorationHandler: nil) return true }
Did not try to import AppsFlyerAttribution in Swift directly (which fails)
➡️ Instead, added this to Bridging Header file in your project:
#import <RNAppsFlyer.h>
This exposes the internal Objective-C implementation from react-native-appsflyer, including AppsFlyerAttribution.
✅ Result: After making this change, onDeepLink() is reliably triggered even on cold start.
This works
Hey Guys, it does not work for me in after adding in the bridging header.. @lennartschoch Where do you think it is fixed ? can you share a link ? Can someone share full swift example
Same issue on react-native project, after update to React Native 0.79.0 and [email protected]
@singhagam1 @MarySnopok
Please add the following changes for AppsFlyer integration using Swift langugae
-
Update the bridge header
#import <RNAppsFlyer.h> -
Modify
AppDelegate.swift
Add the required import:
import AppsFlyerLib
Then include the following methods:
// MARK: - AppsFlyer Deeplink Handling
// iOS 9 and above: Handle URI-scheme deep links
func application(
_ application: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
AppsFlyerLib.shared().handleOpen(url, options: options)
return true
}
// iOS 8 and below: Handle URI-scheme deep links
func application(
_ application: UIApplication,
open url: URL,
sourceApplication: String?,
annotation: Any
) -> Bool {
AppsFlyerLib.shared().handleOpen(url, sourceApplication: sourceApplication, withAnnotation: annotation)
return true
}
// Universal Links handling
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
AppsFlyerLib.shared().continue(userActivity, restorationHandler: { (array: [Any]?) in
restorationHandler(array as? [UIUserActivityRestoring])
})
return true
}
@amitkumarcoding Thank you for sharing but we have those configs at place as those are part of the initial integration manual and they worked well before the upgrade. The issue is exactly how it is specified in the ticket description that performance is inconsistent and it fires 1 in 3 from kill (cold) state.
The solution was found in the sample code.
Bridge header is not required.
https://github.com/AppsFlyerSDK/appsflyer-onelink-ios-sample-apps/blob/a96399329a369b30263ea4f8cc4558029ea603b3/swift/basic_app/basic_app/AppDelegate.swift
// package.json
"react-native": "0.81.1",
"react-native-appsflyer": "^6.17.5",
// AppDelegate.swift
import UIKit
import React
import React_RCTAppDelegate
import ReactAppDependencyProvider
import AppsFlyerLib
@main
class AppDelegate: UIResponder, UIApplicationDelegate, AppsFlyerLibDelegate, DeepLinkDelegate {
var window: UIWindow?
var reactNativeDelegate: ReactNativeDelegate?
var reactNativeFactory: RCTReactNativeFactory?
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
let delegate = ReactNativeDelegate()
let factory = RCTReactNativeFactory(delegate: delegate)
delegate.dependencyProvider = RCTAppDependencyProvider()
reactNativeDelegate = delegate
reactNativeFactory = factory
window = UIWindow(frame: UIScreen.main.bounds)
factory.startReactNative(
withModuleName: "my_app",
in: window,
launchOptions: launchOptions
)
return true
}
// MARK: - AppsFlyerLibDelegate
func onConversionDataSuccess(_ conversionInfo: [AnyHashable : Any]) {
// Handle conversion data success
}
func onConversionDataFail(_ error: Error) {
// Handle conversion data failure
}
// MARK: - DeepLinkDelegate
func didResolveDeepLink(_ result: DeepLinkResult) {
// Handle deep link
}
// MARK: - URL Handling
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
AppsFlyerLib.shared().continue(userActivity, restorationHandler: nil)
return true
}
// Open URI-scheme for iOS 8 and below
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
AppsFlyerLib.shared().handleOpen(url, sourceApplication: sourceApplication, withAnnotation: annotation)
return true
}
// Open URI-scheme for iOS 9 and above
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
AppsFlyerLib.shared().handleOpen(url, options: options)
return true
}
}
class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
override func sourceURL(for bridge: RCTBridge) -> URL? {
self.bundleURL()
}
override func bundleURL() -> URL? {
#if DEBUG
RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
#else
Bundle.main.url(forResource: "main", withExtension: "jsbundle")
#endif
}
}
// util_appsflyer.ts
import { Platform } from 'react-native';
import appsFlyer from 'react-native-appsflyer';
appsFlyer.initSdk(
{
devKey: "123456",
isDebug: true,
appId: "123456",
onInstallConversionDataListener: false,
onDeepLinkListener: true, //Optional
timeToWaitForATTUserAuthorization: 10, //for iOS 14.5
},
() => null,
() => null,
);
// index.js
/**
* @format
*/
import { AppRegistry } from 'react-native';
import { name as appName } from './app.json';
import App from './src/App';
import './src/shared/utils/util_appsflyer';
AppRegistry.registerComponent(appName, () => App);
// useDeepLink.ts
const useDeepLink = () => {
useEffect(() => {
appsFlyer.onDeepLink(result => {
console.log('result', result);
});
return (): void => {
appsFlyer.stop(true);
};
}, []);
};
export default useDeepLink;
useDeepLink();
To handle such cases, you should use
AppsFlyerAttribution,which waits for the bridge to be ready before performing the deep link resolution.
Thank you for the suggestion, it will make things easier for us from now on!
We've been dealing with this issue since upgrading to React Native 0.77, which is the first to have swift based AppDelegate. We've even been in touch with product support with no luck.
Can it be true that it's not mentioned anywhere in the documentation, that you need to do this trick, to support deep links on RN >= 0.77? Seems link new updates to the RN SDK has been released continously in the meantime since RN 77 came out, with no instructions of this kind.
@pazlavi @chizhkov422 many thanks! Wish I can buy you a beer/tee/coffee/${drinkOfYourChoice}
For folks who are rusty on xcode/ios here is an instruction how to create the bridging header
XCode 26.0.1:
- Files>New>File from template>Header
- File Name AppDelegate-Bridging-Header.h file content
#import <RNAppsFlyer.h> - Build Setting > Swift Compiler - General > Objective-C Bridging Header
- Debug/Release: app/AppDelegate-Bridging-Header.h
- Build app
same issue
Is anyone using a fix for a expo managed workflow? (using prebuild)
I'm having the same problem.
RN 0.77.3 appsflyer 6.17.7
Using AppDelegate.mm instead of Swift.
So no expo users?
Thanks a lot for this comment @pazlavi — it helped me identify and solve the exact issue I was facing with deep links not firing on cold start in iOS when using React Native.
For anyone integrating react-native-appsflyer in a Swift-based project, here's what finally worked for me:
✅ Problem: Using AppsFlyerLib.shared() in AppDelegate.swift was causing deep links (especially OneLink) to fail on cold start — exactly as mentioned here: the resolution was happening before the JS bridge was ready.
✅ Fix: Replaced AppsFlyerLib with AppsFlyerAttribution in Swift, like so:
func application( _ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:] ) -> Bool { AppsFlyerAttribution.shared().handleOpen(url, options: options)
// React Native Linking return RCTLinkingManager.application(application, open: url, options: options)}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { AppsFlyerAttribution.shared().continue(userActivity, restorationHandler: nil) return true }
Did not try to import AppsFlyerAttribution in Swift directly (which fails)
➡️ Instead, added this to Bridging Header file in your project:
#import <RNAppsFlyer.h>
This exposes the internal Objective-C implementation from react-native-appsflyer, including AppsFlyerAttribution.
✅ Result: After making this change, onDeepLink() is reliably triggered even on cold start.
Thanks @ahtokca, @pazlavi & @chizhkov422!
This solved the issue for me. I used; "react-native-appsflyer": "~6.17.8" "react-native": "0.81.4",
You have to create bridging header file via Xcode. Below are the steps;
- File > + New > File from Template...
- Name your file with AppDelegate-Header.h for example
- Fill the content with this one line "#import <RNAppsFlyer.h>"
- Open build setting > All Tab
- Find "Swift Compiler - General"
- Expand Objective-C Bridging Header
- Click the plus sign of each of your Build Configuration
- Fill the value with "$(SRCROOT)/AppDelegate-Header.h"
- Change the AppDelegate.swift file, remove "import AppsFlyerLib"
- Change "AppsFlyerLib.shared()" with "AppsFlyerAttribution.shared()"
- AppsFlyerAttribution will be retrieved from your AppDelegate-Header.h file, so no need to "import AppsFlyerAttribution"
- Build the App