Prerequisites

Before you get started, make sure you have the following:
  1. Obtain your publishable key (DUB_PUBLISHABLE_KEY) from your workspace’s Analytics settings page and allowlist your site’s domain (DUB_DOMAIN) to allow the client-side conversion events to be ingested by Dub.
  2. (Optional) If you plan to track conversions, follow the Dub Conversions quickstart guide to enable conversion tracking for your links.

Quickstart

This quick start guide will show you how to get started with Dub iOS SDK in your Swift project.
1

Install the Dub iOS SDK

Before installing, ensure your environment meets these minimum requirements:Build Tools:
  • Xcode 16+
  • Swift 6+
Platforms:
  • iOS 16.0+
  • macOS 10.13 (Ventura)+
The Dub iOS SDK can be installed using the Swift Package Manager.In Xcode, select File > Add Package Dependencies and add https://github.com/dubinc/dub-ios as the repository URL. Select the latest version of the SDK from the release page.
2

Initialize the SDK

You must call Dub.setup with your publishable key and domain prior to being able to use the dub instance.
import SwiftUI
import Dub

@main
struct DubApp: App {
    // Step 1: Obtain your Dub domain and publishable key
    private let dubPublishableKey = "<DUB_PUBLISHABLE_KEY>"
    private let dubDomain = "<DUB_DOMAIN>"

    init() {
        // Step 2: Initialize the Dub SDK by calling `setup`
        Dub.setup(publishableKey: dubPublishableKey, domain: dubDomain)
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
                // Step 3: Expose the `dub` instance as a SwiftUI environment value
                .environment(\.dub, Dub.shared)
        }
    }
}
3

Track deep link open events

Call trackOpen on the dub instance to track deep link and deferred deep link open events. The trackOpen function should be called once without a deepLink parameter on first launch, and then again with the deepLink parameter whenever the app is opened from a deep link.
// ContentView.swift
import SwiftUI
import Dub

struct ContentView: View {

    @Environment(\.dub) var dub: Dub

    @AppStorage("is_first_launch") private var isFirstLaunch = true

    var body: some View {
        NavigationStack {
            VStack {
                // Your app content
            }
            .onOpenURL { url in
                trackOpen(deepLink: url)
            }
            .onAppear {
                if isFirstLaunch {
                    trackOpen()
                    isFirstLaunch = false
                }
            }
        }
    }

    private func trackOpen(deepLink: URL? = nil) {
        Task {
            do {
                let response = try await dub.trackOpen(deepLink: deepLink)

                // Obtain the destination URL from the response
                guard let url = response.link?.url else {
                    return
                }

                // Navigate to the destination URL
            } catch let error as DubError {
                print(error.localizedDescription)
            }
        }
    }
}
4

Track lead events (optional)

To track lead events, call trackLead on the dub instance with your customer’s external ID, name, and email.
// ContentView.swift
import SwiftUI
import Dub

struct ContentView: View {

    @Environment(\.dub) var dub: Dub

    var body: some View {
       // ... your app content ...
    }

    private func trackLead(customerExternalId: String, name: String, email: String) {
        Task {
            do {
                let response = try await dub.trackLead(
                    eventName: "User Sign Up",
                    customerExternalId: customerExternalId,
                    customerName: name,
                    customerEmail: email
                )

                print(response)
            } catch let error as DubError {
                print(error.localizedDescription)
            }
        }
    }
}
5

Track sale events (optional)

To track sale events, call trackSale on the dub instance with your customer’s user ID and purchase information.
iOS (SwiftUI)
// ContentView.swift
import SwiftUI
import Dub

struct ContentView: View {

  @Environment(\.dub) var dub: Dub

  var body: some View {
     // ... your app content ...
  }

  private func trackSale(
      customerExternalId: String,
      amount: Int,
      currency: String = "usd",
      eventName: String? = "Purchase",
      paymentProcessor: PaymentProcessor = .custom,
      invoiceId: String? = nil,
      metadata: Metadata? = nil,
      leadEventName: String? = nil,
      customerName: String? = nil,
      customerEmail: String? = nil,
      customerAvatar: String? = nil
  ) {
      Task {
          do {
              let response = try await dub.trackSale(
                  customerExternalId: customerExternalId,
                  amount: amount,
                  currency: currency,
                  eventName: eventName,
                  paymentProcessor: paymentProcessor,
                  invoiceId: invoiceId,
                  metadata: metadata,
                  leadEventName: leadEventName,
                  customerName: customerName,
                  customerEmail: customerEmail,
                  customerAvatar: customerAvatar
              )

              print(response)
          } catch let error as DubError {
              print(error.localizedDescription)
          }
      }
  }
}

Examples

Here are some open-source code examples that you can reference: