Skip to main content
The deep links module handles deferred deep links — routing users to the correct screen on first launch after installing from a link. This enables attribution tracking, referral programs, and contextual first-launch experiences. A deferred deep link works across the install boundary:
  1. User clicks a link on the web (e.g., https://yourapp.com/workout/123?ref=instagram)
  2. User is redirected to the App Store and installs your app
  3. On first launch, the SDK resolves the original link and returns the destination
AppDNA.checkDeferredDeepLink { deepLink in
    guard let deepLink = deepLink else { return }
    // deepLink.screen = "/workout/123"
    // deepLink.params = ["ref": "instagram"]
    navigate(to: deepLink.screen, params: deepLink.params)
}
checkDeferredDeepLink is a static method on AppDNA. It should be called once on first launch, typically after configure() completes. The SDK returns nil if no deferred link is found or if the app was not installed from a link.
checkDeferredDeepLink is a top-level static method, not part of the deep links module:
AppDNA.checkDeferredDeepLink { deepLink in
    guard let deepLink = deepLink else { return }
    navigate(to: deepLink.screen, params: deepLink.params)
}

Module Access

let deepLinks = AppDNA.deepLinks

Module Methods

MethodSignatureDescription
setDelegatesetDelegate(_ delegate: AppDNADeepLinkDelegate?)Set a delegate for deep link callbacks
handleURLhandleURL(_ url: URL)Pass an incoming URL to the SDK for processing
PropertyTypeDescription
screenStringTarget screen path (e.g., "/workout/123")
params[String: String]Additional parameters (e.g., referrer, campaign)
visitorIdStringThe visitor identifier from the originating link

AppDNADeepLinkDelegate

Register a delegate for deep link events:
protocol AppDNADeepLinkDelegate: AnyObject {
    func onDeepLinkReceived(url: URL, params: [String: String])
}

Example Implementation

class LinkHandler: AppDNADeepLinkDelegate {
    func onDeepLinkReceived(url: URL, params: [String: String]) {
        // Route based on the incoming URL
        route(to: url.path, params: params)
    }

    private func route(to screen: String, params: [String: String]) {
        switch screen {
        case let s where s.hasPrefix("/workout/"):
            let id = String(s.dropFirst("/workout/".count))
            showWorkout(id: id)
        case "/referral":
            showReferralWelcome(referrer: params["ref"])
        default:
            showHome()
        }
    }
}

AppDNA.deepLinks.setDelegate(LinkHandler())

Platform Setup

To support Universal Links on iOS, configure your app:
  1. Enable Associated Domains in your target’s Signing & Capabilities.
  2. Add your domain: applinks:yourapp.com
  3. Host an apple-app-site-association file on your domain.

Handling in AppDelegate or SceneDelegate

Pass incoming URLs to the SDK:
// SceneDelegate
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
    if let url = userActivity.webpageURL {
        AppDNA.deepLinks.handleURL(url)
    }
}

// Or in SceneDelegate for URL schemes
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    if let url = URLContexts.first?.url {
        AppDNA.deepLinks.handleURL(url)
    }
}

Auto-Tracked Events

EventTrigger
deferred_deep_link_resolvedA deferred deep link is resolved on first launch

Full Example

import AppDNASDK

class AppCoordinator: AppDNADeepLinkDelegate {
    init() {
        AppDNA.deepLinks.setDelegate(self)
    }

    func handleFirstLaunch() {
        // Check for deferred deep link on first launch
        AppDNA.checkDeferredDeepLink { [weak self] deepLink in
            if let deepLink = deepLink {
                // User installed from a link -- route to the target screen
                self?.route(to: deepLink.screen, params: deepLink.params)

                // Track the visitor as a user trait
                AppDNA.identify(
                    userId: currentUserId,
                    traits: ["visitor_id": deepLink.visitorId]
                )
            } else {
                // Normal install -- show default onboarding
                self?.showOnboarding()
            }
        }
    }

    // MARK: - AppDNADeepLinkDelegate

    func onDeepLinkReceived(url: URL, params: [String: String]) {
        route(to: url.path, params: params)
    }

    private func route(to screen: String, params: [String: String]) {
        // Route to the correct screen based on the path
    }
}
Deep link routes are configured in the Console under Engagement > Deep Links. The SDK resolves deferred links by checking stored visitor context on first launch.