Old - Unified deep linking

At a glance: Unified deep linking sends new and existing users to a specific in-app activity as soon as the app is opened.


Deep linking directs mobile users into a specific activity or content in an app.

This routing to a specific in-app activity is possible due to the didResolveDeepLink method that carries click data whether or not the users already have the app installed. The AppsFlyer OneLink ensures that the correct parameters are passed along with the user's click when didResolveDeepLink is called, thus personalizing the user’s experience.

The marketer and developer must coordinate regarding desired app behavior and deep_link_value. The marketer uses the parameters to create deep links, and the developer customizes the behavior of the app based on the value received.

The AppsFlyer SDK returns the parameters from the link that the user clicked, and it is the developer's responsibility to make sure the parameters are handled correctly in the app, for both in-app routing, and personalizing data in the link.

The flow works as follows:

  1. User clicks the OneLink short URL.
  2. The iOS Universal Links (for deep linking) or the deferred deep link, trigger the SDK.
  3. The SDK triggers the didResolveDeepLink method, and passes the deep link result object to the user.
  4. The didResolveDeepLink method uses the deep link result object that includes the deep_link_value and other parameters to create the personalized experience for the users, which is the main goal of OneLink.


The unified deep linking API:

  • Requires AppsFlyer iOS SDK V6.1 or later.
  • Does not support SRN campaigns.
  • Does not support the af_dp parameter.


To implement the didResolveDeepLink method and set up the parameter behaviors, the following action checklist of procedures need to be completed.

Procedure checklist

  1. Deciding app behavior and deep_link_value (and other parameter names and values) - with the marketer
  1. Planning method input, i.e. deep_link_value (and other parameter names and values) - with the marketer
  1. Implementing the didResolveDeepLink() logic

Deciding app behavior

To decide what the app behavior is when the link is clicked:

Get from the marketer: The expected behavior of the link when it is clicked.

Planning method input

When the didResolveDeepLink method is called by the AppsFlyer SDK, it gets a deep link object as an input.

The input object is described in the didResolveDeepLink API reference.

The marketer and developers need to plan the deep_link_value (and possible other parameters and values) together based on the desired app behavior when the link is clicked.

To plan the deep_link_value, and other parameter names and values based on the expected link behavior:

  1. Tell the marketer what parameters and values are needed in order to implement the desired app behavior.
  2. Decide on naming conventions for the deep_link_value and other parameters and values.
    Note: Custom parameters will not appear in raw data collected in AppsFlyer.



The marketer and developers need to decide together on the best long term system for the deep_link_value (and any other parameters/values) to minimize additional app updates.

The deep_link_value can be based on a SKU, post ID, path, or anything else. We strongly recommend agreeing with your developers on a system that allows for you to enter dynamic values on your chosen parameter, so you can generate many different deep links that go to different content within the app, without any further changes to the app code by the developers.

See the following URL examples. The deep_link_value of a fruit type was chosen by the marketer and developer together. And the developers made the values dynamic, so the marketer could enter any fruit without the need for further work by the dev team.


Implementing didResolveDeepLink() logic

The iOS Universal Links (for deep linking) and the deferred deep link both trigger the SDK. The SDK triggers the didResolveDeepLink method, that passes the deep link result object to the user. The deep link result object carries an error-handling code, and the deep_link_value and other parameters that implement the specific user experience when the application is opened.

To implement the logic:

  1. Implement the logic based on the chosen parameters and values. See the following code example.
  2. Once completed, send confirmation to the marketer that the app behaves accordingly.


Sample code

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
  AppsFlyerLib.shared().deepLinkDelegate = self

extension AppDelegate: DeepLinkDelegate {
    func didResolveDeepLink(_ result: DeepLinkResult) {
        switch result.status {
        case .notFound:
            print("Deep link not found")
        case .found:
            let deepLinkStr:String = result.deepLink!.toString()
            print("DeepLink data is: \(deepLinkStr)")
            if( result.deepLink?.isDeferred == true) {
                print("This is a deferred deep link")
            } else {
                print("This is a direct deep link")
            walkToSceneWithParams(deepLinkObj: result.deepLink!)
        case .failure:
            print("Error %@", result.error!)
// User logic
fileprivate func walkToSceneWithParams(deepLinkObj: DeepLink) {
    let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    UIApplication.shared.windows.first?.rootViewController?.dismiss(animated: true, completion: nil)
    guard let fruitNameStr = deepLinkObj.clickEvent["deep_link_value"] as? String else {
         print("Could not extract query params from link")
    let destVC = fruitNameStr + "_vc"
    if let newVC = storyBoard.instantiateVC(withIdentifier: destVC) {
       print("AppsFlyer routing to section: \(destVC)")
       newVC.deepLinkData = deepLinkObj
       UIApplication.shared.windows.first?.rootViewController?.present(newVC, animated: true, completion: nil)
    } else {
        print("AppsFlyer: could not find section: \(destVC)")

⇲ Github links: Swift

Did this page help you?