WarpLink
SDKsiOS

Deep Links

Handle Universal Links for iOS deep linking with WarpLink.

When a user taps a WarpLink URL and your app is installed, iOS opens your app via Universal Links. The SDK resolves the URL into a WarpLinkDeepLink with the destination, custom parameters, and attribution data.

@main
struct MyApp: App {
    init() {
        WarpLink.configure(apiKey: "wl_live_your_api_key_here_abcdefgh")
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
                .onOpenURL { url in
                    WarpLink.handleDeepLink(url) { result in
                        switch result {
                        case .success(let deepLink):
                            navigateTo(deepLink.destination)
                        case .failure(let error):
                            print("Error: \(error.localizedDescription)")
                        }
                    }
                }
        }
    }
}
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
        guard let url = userActivity.webpageURL else { return }

        WarpLink.handleDeepLink(url) { result in
            switch result {
            case .success(let deepLink):
                navigateTo(deepLink.destination)
            case .failure(let error):
                print("Error: \(error.localizedDescription)")
            }
        }
    }
}

The completion handler is always called on the main thread, so you can safely update UI from it.

Cold Start vs Warm Start

ScenarioEntry PointBehavior
Cold startApp not running — system launches itonOpenURL / scene(_:continue:) fires once the app is ready
Warm startApp in background — brought to foregroundonOpenURL / scene(_:continue:) fires immediately

Both cases use the same handler. The SDK automatically resolves the link by calling the WarpLink API.

WarpLink.handleDeepLink(url) { result in
    if case .success(let deepLink) = result {
        print("Link ID: \(deepLink.linkId)")
        print("Destination: \(deepLink.destination)")

        // iOS-specific deep link URL (e.g., myapp://product/123)
        if let deepLinkUrl = deepLink.deepLinkUrl {
            navigateToPath(deepLinkUrl)
        }

        // Custom parameters attached to the link
        if let productId = deepLink.customParams["product_id"] as? String {
            showProduct(id: productId)
        }
    }
}

Error Handling

WarpLink.handleDeepLink(url) { result in
    switch result {
    case .success(let deepLink):
        navigateTo(deepLink.destination)
    case .failure(let error):
        switch error {
        case .notConfigured:
            // SDK not initialized — call configure() first
            break
        case .invalidURL:
            // Not a WarpLink URL (not aplnk.to domain)
            break
        case .linkNotFound:
            // Link deleted or expired
            showLinkExpired()
        case .networkError:
            // No connectivity — retry or show offline state
            showOfflineMessage()
        case .serverError(let code, let message):
            print("Server error \(code): \(message)")
        default:
            print("Error: \(error.localizedDescription)")
        }
    }
}

Verify AASA Configuration

WarpLink generates the Apple App Site Association file automatically. Verify it's served correctly:

curl https://aplnk.to/.well-known/apple-app-site-association

The response should contain your Team ID and Bundle ID in the applinks section.

After adding Associated Domains, you may need to delete and reinstall the app for iOS to re-fetch the AASA file.

On this page