Swift

How to Add the Linkkit iOS SDK to Your Swift Project

How to Add the Linkkit iOS SDK to Your Swift Project

Prerequisites

Before getting started, make sure you have the following:

  • Obtain your publishable key (LINKKIT_PUBLISHABLE_KEY) from your workspace’s Tracking Settings page.
  • Keep your custom domain (LINKKIT_DOMAIN) ready for configuration.
  • (Optional) If you plan to track conversions, make sure conversion tracking is enabled for your links.

Quick Start

This quick-start guide will walk you through the steps to integrate the Linkkit iOS SDK into your Swift project and help you get started with link tracking and conversion tracking.

1.Install the Linkkit iOS SDK

Before installing the SDK, make sure your development environment meets the following minimum requirements:

Build Tools:

  • Xcode 16+
  • Swift 4.0+

Platforms:

  • iOS 16.0+
  • macOS 10.13 (Ventura)+

The Linkkit iOS SDK can be installed using the Swift Package Manager.

In Xcode, go to File > Add Package Dependencies and add the following repository URL:

https://github.com/linkkit/linkkit-ios

Then, select the latest available SDK version from the releases page.


2. Initialize the SDK

Before using the Linkkit instance, you must initialize the SDK by calling Linkkit.setup with your publishable key and domain.

import SwiftUI
import LinkKit

@main
struct LinkKitApp: App {
    // Step 1: Obtain your LinkKit domain and publishable key
    private let linkkitPublishableKey = "<LINKKIT_PUBLISHABLE_KEY>"
    private let linkkitDomain = "<LINKKIT_DOMAIN>"

    init() {
        // Step 2: Initialize the LinkKit SDK by calling `setup`
        LinkKit.setup(publishableKey: linkkitPublishableKey, domain: linkkitDomain)
    }

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

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    // Step 1: Obtain your LinkKit domain and publishable key
    private let linkkitPublishableKey = "<LINKKIT_PUBLISHABLE_KEY>"
    private let linkkitDomain = "<LINKKIT_DOMAIN>"

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Step 2: Initialize the LinkKit SDK by calling `setup`
        LinkKit.setup(publishableKey: linkkitPublishableKey, domain: linkkitDomain)
        return true
    }
}


3. Track Deep Link Open Events

Use the trackOpen method on the Linkkit instance to track both deep link and deferred deep link open events.

The trackOpen method should be called:

  • Once on the app's first launch without providing a deepLink parameter.
  • Again whenever the app is opened through a deep link, passing the deepLink parameter with the incoming URL.

This allows Linkkit to accurately attribute app opens and user activity to the appropriate referral links.

UIKit URL Handler Setup
If your AppDelegate uses multiple URL handlers chained with || (for example, Facebook/Meta SDK alongside Linkkit), short-circuit evaluation may prevent handleDeepLink and trackOpen from running. Ensure all handlers execute independently. Check the troubleshooting guide for details and the recommended fix.
// ContentView.swift
import SwiftUI
import LinkKit

struct ContentView: View {

    @Environment(\.linkkit) var linkkit: LinkKit

    @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 linkkit.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 LinkKitError {
                print(error.localizedDescription)
            }
        }
    }
}
// ContentView.swift
import SwiftUI
import LinkKit

struct ContentView: View {

    @Environment(\.linkkit) var linkkit: LinkKit

    @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 linkkit.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 LinkKitError {
                print(error.localizedDescription)
            }
        }
    }
}


4. Track Lead Events (Optional)

To track lead events, call the trackLead method on the Linkkit instance and provide the customer’s external ID, name, and email.

This allows Linkkit to identify the customer and associate future conversion events with the correct user and referral source.

// ContentView.swift
import SwiftUI
import LinkKit

struct ContentView: View {

    @Environment(\.linkkit) var linkkit: LinkKit

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

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

                print(response)
            } catch let error as LinkKitError {
                print(error.localizedDescription)
            }
        }
    }
}
// ViewController.swift
import UIKit
import LinkKit

class ViewController: UIViewController {
    // View controller lifecycle...

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

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


5. Track Sale Events (Optional)

To track sale events, call the trackSale method on the Linkkit instance and provide the customer’s user ID along with the relevant purchase details.

This allows Linkkit to record completed transactions, attribute revenue to the correct referral source, and provide accurate conversion tracking.

// ContentView.swift
import SwiftUI
import LinkKit

struct ContentView: View {

  @Environment(\.linkkit) var linkkit: LinkKit

  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 linkkit.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 LinkKitError {
              print(error.localizedDescription)
          }
      }
  }
}
// ViewController.swift
import UIKit
import LinkKit

class ViewController: UIViewController {
    // View controller lifecycle...

  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 LinkKit.shared.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 LinkKitError {
              print(error.localizedDescription)
          }
      }
  }
}


Examples

Here are some open-source code examples you can use as a reference: