iOS SDK
Install and integrate the LinkTrail iOS SDK — module LinkTrailSDK, iOS 15+.
Binary XCFramework · module LinkTrailSDK · entry point LinkTrail · iOS 15+, Swift 5.9 / Xcode 15+ · Swift Package Manager or CocoaPods.
Install
Swift Package Manager
In Xcode: File → Add Package Dependencies… → paste the repo URL → pick a version. Or in a Package.swift:
.package(url: "https://github.com/linktrail-io/ios-sdk.git", from: "0.0.8")CocoaPods
pod 'LinkTrailSDK', '~> 0.0.8'Then run pod install and open the generated .xcworkspace.
Integrate
import LinkTrailSDK
// At launch (SwiftUI App.init or AppDelegate). The API key is required — configure throws.
// The install is tracked automatically.
try LinkTrail.configure(apiKey: "lt_live_...")
// One hook — fires for deferred (first-launch) AND re-engagement links:
LinkTrail.shared?.onLink { link, source in
router.route(to: link.path, customData: link.customData)
}
LinkTrail.shared?.onError { error in /* e.g. LinkTrailError.invalidAPIKey */ }Forward incoming links — SwiftUI:
.onOpenURL { LinkTrail.shared?.handleDeepLink($0) }
.onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { activity in
if let url = activity.webpageURL { LinkTrail.shared?.handleDeepLink(url) }
}Or UIKit, from your SceneDelegate:
// Universal Links (app already running or cold-started from a link):
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
if let url = userActivity.webpageURL { LinkTrail.shared?.handleDeepLink(url) }
}
// Custom schemes (yourapp://…):
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
URLContexts.forEach { LinkTrail.shared?.handleDeepLink($0.url) }
}handleDeepLink returns false for URLs that aren't LinkTrail links, so you can fall through to your own routing. Every callback API also has an async throws twin (e.g. try await LinkTrail.shared?.handleDeepLink(url) returns the resolved link). Callbacks are delivered on the main thread.
More
// Custom + revenue events:
LinkTrail.shared?.trackEvent(name: "purchase", value: 59.99, currency: "USD")
// Cached results:
let attribution = LinkTrail.shared?.lastAttribution
let lastLink = LinkTrail.shared?.lastDeepLink
// Attribution hook (fires when an install is attributed):
LinkTrail.shared?.onAttribution { attribution in /* … */ }
// Consent-gated install (defer configure's auto-track, then call manually):
let lt = try LinkTrail.configure(apiKey: "lt_live_...",
options: LinkTrailOptions(autoTrackInstall: false))
lt.trackInstall()
// ATT / SKAdNetwork:
await LinkTrail.shared?.requestTrackingAuthorization()
LinkTrail.shared?.registerForSKAdAttribution()
LinkTrail.shared?.updateConversionValue(42, coarseValue: .medium)Options & defaults
| LinkTrailOptions field | Default | Notes |
|---|---|---|
| logEnabled | false | Master switch for SDK logging |
| logLevel | .info | .debug · .info · .warning · .error · .none |
| requestTimeout | 15 s | Per-request network timeout |
| retryPolicy | .default | 3 attempts, 0.5 s base / 8 s max backoff; .disabled turns retries off |
| linkDomains | [] (all hosts) | See the warning under Deep-link setup before setting this |
| autoTrackInstall | true | false = consent-gated; call trackInstall() yourself |
API surface
| API | Purpose |
|---|---|
| configure(apiKey:options:) | Initialize; auto-tracks the install |
| onLink { link, source } | Deep link delivered (deferred + re-engagement) |
| onAttribution { attribution } | Install attribution result |
| onError { error } | Failures (invalid key, network…) |
| handleDeepLink(url) | Forward Universal Links / custom schemes |
| trackEvent(name:value:currency:) | Custom + revenue events |
| trackInstall(force:) | Manual install track (with autoTrackInstall: false) |
| lastAttribution / lastDeepLink | Cached last results |
| requestTrackingAuthorization() | ATT prompt wrapper |
| registerForSKAdAttribution() / updateConversionValue(_:coarseValue:) | SKAdNetwork |
Deep-link setup
Add the Associated Domains capability with applinks:yourapp.linktrail.io. For a custom scheme, add it under CFBundleURLTypes in Info.plist.
App Store privacy
The SDK ships its own privacy manifest (PrivacyInfo.xcprivacy), so Xcode's privacy report includes it automatically. What it declares: a per-install device identifier (IDFV, with a UUID fallback) linked to the user, used for Analytics and App Functionality; no IDFA collection; no cross-company tracking (NSPrivacyTracking = false). In App Store Connect's App Privacy questionnaire, count LinkTrail as: Identifiers → Device ID, linked to the user, not used for tracking.